1.简介
CyclicBarrier是一个同步工具类,它可以实现让一组线程互相等待至某个状态之后再全部同时执行。当所有等待线程都被释放以后,CyclicBarrier可以被重用。
2.常用API
Method | Description |
---|---|
int await() | Waits until all parties have invoked await on this barrier. |
int await(long timeout, TimeUnit unit) | Waits until all parties have invoked await on this barrier, or the specified waiting time elapses. |
int getNumberWaiting() | Returns the number of parties currently waiting at the barrier. |
int getParties() | Returns the number of parties required to trip this barrier. |
boolean isBroken() | Queries if this barrier is in a broken state. |
void reset() | Resets the barrier to its initial state. |
3.API使用
-
5个线程相互等待至都阻塞之后,所有线程一起执行,它也可以用于最大并发测试,或者死锁检测
public class TempDemo { private static final int threadCount = 5; public static void main(String[] args) throws Exception { CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount, ()->{ System.out.println(Thread.currentThread().getName() + " 等待线程达到临界点5,5个线程都执行"); }); Thread[] threads = new Thread[threadCount]; for(int index = 0; index < threadCount; index ++) { threads[index] = new Thread(() -> { try { System.out.println(Thread.currentThread().getName() + " parties:" + cyclicBarrier.getParties()); System.out.println(Thread.currentThread().getName() + " wait threads:" + (cyclicBarrier.getNumberWaiting() + 1) + "\n"); cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }); threads[index].start(); TimeUnit.SECONDS.sleep(1); } for (Thread thread : threads) { thread.join(); } System.out.println(Thread.currentThread().getName() + " isBroken:" + cyclicBarrier.isBroken()); } }
-
将上面的cyclicBarrier.await()改为cyclicBarrier.await(1, TimeUnit.SECONDS),代码如下。我们会发现一个Timeout异常,其他都是BrokenBarrier异常。这时CyclicBarrier已经被破坏,调用reset才能重置至初始化状态
public class TempDemo { private static final int threadCount = 5; public static void main(String[] args) throws Exception { CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount, ()->{ System.out.println(Thread.currentThread().getName() + " 等待线程达到临界点5,5个线程都执行"); }); Thread[] threads = new Thread[threadCount]; for(int index = 0; index < threadCount; index ++) { threads[index] = new Thread(() -> { try { System.out.println(Thread.currentThread().getName() + " parties:" + cyclicBarrier.getParties()); System.out.println(Thread.currentThread().getName() + " wait threads:" + (cyclicBarrier.getNumberWaiting() + 1) + "\n"); cyclicBarrier.await(1, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); System.out.println(Thread.currentThread().getName() + " InterruptedException"); } catch (BrokenBarrierException e) { e.printStackTrace(); System.out.println(Thread.currentThread().getName() + " BrokenBarrierException"); } catch (TimeoutException e) { e.printStackTrace(); System.out.println(Thread.currentThread().getName() + " TimeoutException"); } }); threads[index].start(); TimeUnit.SECONDS.sleep(1); } for (Thread thread : threads) { thread.join(); } if (cyclicBarrier.isBroken()) { System.out.println(Thread.currentThread().getName() + " CyclicBarrier被破坏了重置"); cyclicBarrier.reset(); } for(int index = 0; index < 10; index ++) { new Thread(() -> { try { System.out.println(Thread.currentThread().getName() + " parties:" + cyclicBarrier.getParties()); System.out.println(Thread.currentThread().getName() + " wait threads:" + (cyclicBarrier.getNumberWaiting() + 1) + "\n"); cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }).start(); TimeUnit.SECONDS.sleep(1); } } }