JDK的并发包里提供了几个非常有用的工具类:
- CountDownLatch
- CyclicBarrier
- Semaphore:提供了一种并发流程控制的手段.
- Exchanger:在线程间交换数据的一种手段.
一. CountDownLatch:等待多线程完成
CountDownLatch允许一个或多个线程等待其他线程完成操作.
public class CountDownLatchTest{
static CountDownLatch c = new CountDownLatch(2);
public void main(){
new Thread(
new Runnable(){
public void run(){
c.countDown();
c.countDown();
}
}
).start();
c.await();
}
}
CountDownLatch的构造函数接收一个int类型的参数作为计数器.
当调用countDown方法时,N就会减一,CountDownLatch的await方法会阻塞当前线程,直到N变成0.
超时问题可以使用await(long time,TimeUtil unit);
二.CyclicBarrier:同步屏障
让一组线程到达一个屏障(同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续执行.
public class CyclicBarrierTest{
static CyclicBarrier c = new CyclicBarrier(2);
public static void mian(){
new Thread(
public void run(){
try{
c.await();
}
}
).start();
c.await();
}
}
CyclicBarrier还提供了一个更高级的构造函数CyclicBarrier(int parties,Runnable barrier-Action),用于在线程到达屏障时,有限执行barrierAction.
CyclicBarrier和CountDownLatch的区别:
- CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset()方法重置.
- CyclicBarrier还提供其他有用的方法:getNumberWaiting可以获得阻塞的线程数量.isBroken()方法用来了解阻塞的线程是否被中断.
三. Semaphore:控制并发线程数
用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源.
Semphore可以用于做流量控制.
public class SempaphoreTest{
private static Semaphore s = new Semaphore(10);
s.acquire(); //获取凭证
s.tryAcquire();//尝试获取凭证
s.release();//释放凭证
s.intavailablePermits();
s.intgetQueueLength();
s.booleanhasQueuedThreads();
s.reducePermits(int reduction);
s.getQueuedThreds();
}
四. Exchanger:线程间交换数据
用于线程间协作的工具类.线程间的数据交换.
public class ExchangerTest{
private static final Exchanger<String> exgr = new Exchanger<>();
String b = exgr.exchanger("a");
}
如果有一个线程没有执行exchange()方法,则会一直等待.可以使用exchange(V x,longtimeout,TimeUnit unit)