Java并发(十三):并发工具类——同步屏障Cycli…
2018-11-20 03:23:06来源:博客园 阅读 ()
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。
一、应用举例
public class CyclicBarrierTest { private static CyclicBarrier cyclicBarrier; static class CyclicBarrierThread extends Thread { public void run() { System.out.println(Thread.currentThread().getName() + "到了"); try { cyclicBarrier.await(); } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { cyclicBarrier = new CyclicBarrier(5, new Runnable() { @Override public void run() { System.out.println("人到齐了,开会吧...."); } }); for (int i = 0; i < 5; i++) { new CyclicBarrierThread().start(); } } }
二、类结构
public class CyclicBarrier { private static class Generation { // 内部类,当有parties个线程到达barrier,就会更新换代 boolean broken = false; // 是否损坏 } private final ReentrantLock lock = new ReentrantLock(); // 重入锁 private final Condition trip = lock.newCondition(); private final int parties; // 等待线程总数量 private final Runnable barrierCommand; // 达到等待线程数量后执行的线程 private Generation generation = new Generation(); // 当有parties个线程到达barrier,就会更新换代 private int count; // 记录当前线程数量 public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } public CyclicBarrier(int parties) { this(parties, null); } }
三、原理解析
public int await() throws InterruptedException, BrokenBarrierException { try { return dowait(false, 0L); } catch (TimeoutException toe) { throw new Error(toe); // cannot happen } } private int dowait(boolean timed, long nanos) throws InterruptedException, BrokenBarrierException, TimeoutException { final ReentrantLock lock = this.lock; lock.lock(); try { final Generation g = generation; if (g.broken) throw new BrokenBarrierException(); if (Thread.interrupted()) { breakBarrier(); // 代失效,唤醒所有线程 throw new InterruptedException(); } int index = --count; // 计数 if (index == 0) { // 达到要求数量 boolean ranAction = false; try { final Runnable command = barrierCommand; if (command != null) command.run(); // 达到等待线程数量后执行barrierCommand ranAction = true; nextGeneration(); // 唤醒本代所有线程,生成新一代,重置count return 0; } finally { if (!ranAction) breakBarrier(); } } // 线程数量未达到要求数量,将线程挂起等待 for (;;) { try { if (!timed) trip.await(); // 将线程加入condition队列挂起 else if (nanos > 0L) nanos = trip.awaitNanos(nanos); } catch (InterruptedException ie) { if (g == generation && !g.broken) { breakBarrier(); throw ie; } else { Thread.currentThread().interrupt(); } } // 特殊情况处理 if (g.broken) throw new BrokenBarrierException(); if (g != generation) return index; if (timed && nanos <= 0L) { breakBarrier(); throw new TimeoutException(); } } } finally { lock.unlock(); } } // 代失效,唤醒所有线程 private void breakBarrier() { generation.broken = true; count = parties; trip.signalAll(); } // 唤醒本代所有线程,生成新一代,重置count private void nextGeneration() { trip.signalAll(); count = parties; generation = new Generation(); }
并发工具类(二)同步屏障CyclicBarrier
【死磕Java并发】—–J.U.C之并发工具类:CyclicBarrier
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 国外程序员整理的Java资源大全(全部是干货) 2020-06-12
- 2020年深圳中国平安各部门Java中级面试真题合集(附答案) 2020-06-11
- 2020年java就业前景 2020-06-11
- 04.Java基础语法 2020-06-11
- Java--反射(框架设计的灵魂)案例 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash