这几天在网上看到一篇 java线程 障碍器的微博,学习后有一些体会, 首先先明白它的设计思想,我的理解,站在障碍器的角度,所有的线程任务分为两类,主任务和子任务,现在假设我们有这个一个需求 有3个线程 A 线程B 线程C 在线程A和B开始之后才能开始线程C。对于障碍器来说,A B即为子任务,C即为主任务,只有当A B任务开始之后 ,通知障碍器,障碍器才开始C的start(), 代码实现很简单,我们先看一下 障碍器的api java.util.concurrent.CyclicBarrier;
子任务
运行结果为
/**
* Creates a new <tt>CyclicBarrier</tt> that will trip when the
* given number of parties (threads) are waiting upon it, and which
* will execute the given barrier action when the barrier is tripped,
* performed by the last thread entering the barrier.
*
* @param parties the number of threads that must invoke {@link #await}
* before the barrier is tripped
* @param barrierAction the command to execute when the barrier is
* tripped, or {@code null} if there is no action
* @throws IllegalArgumentException if {@code parties} is less than 1
*/
public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
}
这个是它的一个有参构造,第一个参数是次数,第二个参数是线程任务即咱们的主任务, 可以理解为,当障碍器被通知parties次时,开始线程barrierActionji
代码实现为
/**
* 主任务
* @author zx
*/
public class MainTask implements Runnable{
private String name;
public MainTask(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("主任务 ["+name+"] Start");
}
}
子任务
/**
* 子任务
* @author zx
*/
public class SubTask implements Runnable{
private String name;
private CyclicBarrier cyclicBarrier;
public SubTask(String name,CyclicBarrier cyclicBarrier) {
this.name = name;
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("子任务["+name+"]start");
for (int i = 0; i < 999; i++);//模拟耗时任务、
System.out.println("子任务["+name+"]执行完毕,通知障碍器已经完成");
try {
//通知障碍器已经完成
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* java线程 特性--障碍器O
* @author zx
*
*/
public class TestMainTask extends Thread{
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new MainTask("C"));
new Thread(new SubTask("A", cyclicBarrier)).start();
new Thread(new SubTask("B", cyclicBarrier)).start();
}
}
运行结果为
子任务[A]start
子任务[B]start
子任务[B]执行完毕,通知障碍器已经完成
子任务[A]执行完毕,通知障碍器已经完成
主任务 [C] Start
当然,我们要明白它的使用场景,只有在主任务 明确知道 子任务 准确次数通知的情况下,才适用