CyclicBarrier
时间:2020-01-09 10:36:26 来源:igfitidea点击:
java.util.concurrent.CyclicBarrier
类是一种同步机制,可以同步通过某种算法进行的线程。换句话说,这是所有线程必须继续等待直到所有线程到达它的屏障。
线程通过在CyclicBarrier
上调用await()
方法来互相等待。一旦N个线程在" CyclicBarrier"上等待,所有线程将被释放并可以继续运行。
创建一个CyclicBarrier
当创建一个" CyclicBarrier"时,我们指定释放它之前要等待多少个线程。这是创建" CyclicBarrier"的方法:
CyclicBarrier barrier = new CyclicBarrier(2);
在CyclicBarrier中等待
这是线程在CyclicBarrier
中等待的方式:
barrier.await();
我们还可以为等待的线程指定超时。当超时时间过去后,即使不是所有的N个线程都在" CyclicBarrier"上等待,该线程也会被释放。这是我们指定超时的方法:
barrier.await(10, TimeUnit.SECONDS);
等待线程在CyclicBarrier
处等待,直到:
- 最后一个线程到达(调用await())
- 该线程被另一个线程中断(另一个线程调用其interrupt()方法)
- 另一个等待线程被中断
- 在
CyclicBarrier
中等待时,另一个等待线程超时 - 某些外部线程会调用" CyclicBarrier.reset()"方法。
循环屏障动作
" CyclicBarrier"支持屏障操作,这是一个" Runnable",在最后一个线程到达时执行。我们将" Runnable"屏障操作传递给其构造函数中的" CyclicBarrier",如下所示:
Runnable barrierAction = ... ; CyclicBarrier barrier = new CyclicBarrier(2, barrierAction);
CyclicBarrier示例
这是一个代码示例,向我们展示如何使用CyclicBarrier
:
Runnable barrier1Action = new Runnable() { public void run() { System.out.println("BarrierAction 1 executed "); } }; Runnable barrier2Action = new Runnable() { public void run() { System.out.println("BarrierAction 2 executed "); } }; CyclicBarrier barrier1 = new CyclicBarrier(2, barrier1Action); CyclicBarrier barrier2 = new CyclicBarrier(2, barrier2Action); CyclicBarrierRunnable barrierRunnable1 = new CyclicBarrierRunnable(barrier1, barrier2); CyclicBarrierRunnable barrierRunnable2 = new CyclicBarrierRunnable(barrier1, barrier2); new Thread(barrierRunnable1).start(); new Thread(barrierRunnable2).start();
这是CyclicBarrierRunnable
类:
public class CyclicBarrierRunnable implements Runnable{ CyclicBarrier barrier1 = null; CyclicBarrier barrier2 = null; public CyclicBarrierRunnable( CyclicBarrier barrier1, CyclicBarrier barrier2) { this.barrier1 = barrier1; this.barrier2 = barrier2; } public void run() { try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " waiting at barrier 1"); this.barrier1.await(); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " waiting at barrier 2"); this.barrier2.await(); System.out.println(Thread.currentThread().getName() + " done!"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }
这是执行上述代码的控制台输出。请注意,线程执行写入控制台的顺序可能因执行而异。有时会先显示"线程-0",有时会先打印" Thread-1",依此类推。
Thread-0 waiting at barrier 1 Thread-1 waiting at barrier 1 BarrierAction 1 executed Thread-1 waiting at barrier 2 Thread-0 waiting at barrier 2 BarrierAction 2 executed Thread-0 done! Thread-1 done!