------本文主要记录CountDownLatch,CyclicBarries、Semaphore工具提供的并发流程控制手段
等待多线程完成的CountDownLatch
允许一个或多个线程等待其它线程完成操作,首先我会想到之前看过的fork/join框架 中的join 等待某线程执行完再返回,这个函数的实际功能是循环判断线程是否存活如果不存活就 wait(0)永远的等待下去。然而jdk5之后对countdownlatch有优化为了不让主线程一直等待,就使用另外一个await(long time,TimeUtil util) 实则回一个特定时间就返回 而不管线程是否存活。
static CountDownLarch c = new CountDownLatch(n)
//每执行一次countDown方法 n值减1 n为0之后 就从await()返回
同步屏障 CyclicBarrier
让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所以被屏障拦截的线程才会继续运行。
public class CyclicBarrierTest{
static CyclicBarrier c = new CyclicBarrier(2);
public static void main(String[] args){
new Thread(new Runnable() {
public void run(){
try{
c.await();
}catch(Exception e){
}
system.out.println(1);
}
}).start();
//调用await()意思是告知CyclicBarrier此线程已
//到达屏障,然后当前线程被阻塞直所有线程都到了
try{
c.await();
}catch(Exception e){
}
system.out.println(1);
}
}
输出可能是 12 也可能是21 因线程调度由cpu决定两个线程都可能先执行到同步屏障, 参数2表示屏障需要等待两个线程到达才会开门。
Cyclicbarrier还可以有一个参数
CyclicBarrier(int parties,Runnable barrierAction);
表示线程到达屏障时优先执行barrierAction类的run方法。
CyclicBarrier和CountDownLatch的区别
CountDownLatch的计数器只能有用一次,而CyclicBarrier计数器可以reset(),所以后者更实用业务更加复杂的场景。
CyclicBarrier还有其他的方法 如getNumberWaiting用来获取屏障阻塞的线程数量 isBroken用来了解阻塞的线程是否被中断,所谓线程阻塞就是被动的在抢占资源中得不到资源,被动的挂起在内存,等待某种信号源或信号量将他唤醒(只释放CPU不释放内存。)
控制并发线程数的Semaphore
信号量,用来控制访问特定资源的线程数量,协调线程以保证合理的使用公共资源,
应用场景
- 流量控制
Semaphore s = new Semaphore(10);
//10表示允许10个线程并发执行通过s.aquire()获取 s.release归还使用权。
线程间交换数据的Exchanger
用于进行线程间的数据交换,它提供一个同步点,到达这个同步点两个线程就会交换彼此的数据,只有两个线程都执行了exchange方法,都到达同步点时,两个线程就可以交换数据
这个工具可用于遗传算法,校对工作。
网友评论