1.栅栏与闭锁的区分
相同点:栅栏类似与闭锁,都能阻塞一组线程直到某个事件的发生。
不同点:闭锁是一次性对象,一旦终止就不能被重置,一般用于等待事件。
栅栏是所有的线程必须都到达栅栏的位置,才能继续执行,一般用于等待其他线程,以及实现一些协议。比如:几个家庭决定在某个地方集合:“所有人6:00”在麦当劳集合,到了以后等待其他人,之后在讨论下一步要做的事情。
2.CyclicBarrier的使用
注意:CyclicBarrier在并行迭代算法中非常有用:这种算法通常是将一个问题分拆成一系列相互独立的子问题。
2.1几个方法介绍
CyclicBarrier(int parties)
创建一个新的 CyclicBarrier,当给定数量的参与者(线程)处于等待状态时,启动,但它不会执行预定义的操作。
CyclicBarrier(int parties, Runnable barrierAction)
创建一个新的 CyclicBarrier,当给定数量的参与者(线程)处于等待状态时,启动,并在启动时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行
await()
在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
2.2cyclicBarrier具体使用
场景:大学毕业后,同一个寝室的3个基友都来北京工作,打算这周六小聚一下…
/**
* @author zpf
* @date 2019年1月5日
*/
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "说:兄弟们,不好意思我是最后一个到的,今晚请基友们去做苍朗朗的大保健...");
}
});
CyclicBarrierDemo demo = new CyclicBarrierDemo();
Thread thread1 = new Thread(demo.new Worker(cyclicBarrier));
thread1.setName("骚飞");
thread1.start();
Thread thread2 = new Thread(demo.new Worker(cyclicBarrier));
thread2.setName("骚樊");
thread2.start();
Thread thread3 = new Thread(demo.new Worker(cyclicBarrier));
thread3.setName("鸡哥");
thread3.start();
}
public class Worker implements Runnable {
private final CyclicBarrier cyclicBarrier;
public Worker(CyclicBarrier barrier) {
this.cyclicBarrier = barrier;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "往麦当劳走");
Random random = new Random();
try {
Thread.sleep(random.nextInt(30));
System.out.println(Thread.currentThread().getName() + "到达麦当劳");
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
打印结果如下:
骚飞往麦当劳走
鸡哥往麦当劳走
骚樊往麦当劳走
骚飞到达麦当劳
骚樊到达麦当劳
鸡哥到达麦当劳
鸡哥说:兄弟们,不好意思我是最后一个到的,今晚请基友们去做苍朗朗的大保健…