【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
Java5中,添加了障碍器类,为了适应一种新的设计需求,比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择障碍器了。障碍器是多线程并发控制的一种手段
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。
CountDownLatch介绍:http://my.oschina.net/jielucky/blog/157946
- Java线程:新特征-障碍器 -主线程
package com.thread.cyclicBarrier;
/**
* Java线程:新特征-障碍器 -主线程
* @author wangjie
*
*/
public class MainTask implements Runnable {
@Override
public void run() {
System.out.println("主线程执行了");
}
}
- Java线程:新特征-障碍器 -主线程
package com.lucky.concurrent.cyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* Java线程:新特征-障碍器 -子线程
*
* @author wangjie
*
*/
public class ChildTask extends Thread {
private CyclicBarrier cb;
private static int index = 0;
ChildTask(CyclicBarrier cb) {
this.cb = cb;
}
@Override
public void run() {
try {
if (index >= 2) {
Thread.sleep(3000);
}
index++;
System.out.println("子线程执行完毕,通知主线程");
// 注:这里parties里的计数在运行时当调用CyclicBarrier:await()时,计数就加1,一直加到初始的值
cb.await(); // 通知障碍器已经完成
System.out.println("一定要等到主线程执行之后才会执行 awati() 下面的 代码");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
- Java线程:新特征-障碍器 <testClass>
package com.thread.cyclicBarrier;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Java线程:新特征-障碍器
*
* @author wangjie 2013-08-26 17:03:10
*/
public class TestCyclicBarrier {
public void run() {
// 创建障碍器,并设置MainTask为所有定数量的线程都达到障碍点时候所要执行的任务(Runnable)
CyclicBarrier cb = new CyclicBarrier(4, new MainTask());
ExecutorService pool = Executors.newCachedThreadPool();
pool.execute(new ChildTask(cb));
pool.execute(new ChildTask(cb));
pool.execute(new ChildTask(cb));
pool.execute(new ChildTask(cb));
pool.shutdown();
// pool.shutdownNow();//有线程还没执行完,不能立即停止。只能调用shutdown()
}
public static void main(String[] args) {
new TestCyclicBarrier().run();
}
}
执行结果可以看出,所有子任务完成的时候,主任务执行了,达到了控制的目标。
注:这里parties里的计数在运行时当调用CyclicBarrier:await()时,计数就加1,一直加到初始的值。
以下比方是摘录其他文章:
CountDownLatch 是计数器, 线程完成一个就记一个, 就像 报数一样, 只不过是递减的.
CyclicBarrier更像一个水闸, 线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流. PS:这个形容很到位滴。
来源:oschina
链接:https://my.oschina.net/u/1247185/blog/157001