1. import java.util.concurrent.ThreadLocalRandom;
  2. import java.util.concurrent.TimeUnit;
  3.  
  4. public class Test {
  5. public static void main(String[] args){
  6. // ProgrammerTravleTest.test();
  7. ProgrammerTravleTest.test2();
  8. }
  9. }
  10.  
  11. /*
  12. 第23章 Latch 设计模式
  13.  
  14. 若干线程并发执行某个特定的任务,然后等到所有的子任务都执行结束之后再统一汇总。
  15.  
  16. 23.2 CountDownLatch程序实现
  17.  
  18. 23.2.1 无限等待的Latch
  19. */
  20. class WaitTimeoutException extends Exception{
  21. public WaitTimeoutException(String msg) {
  22. super(msg);
  23. }
  24. }
  25.  
  26. abstract class Latch{
  27. protected int limit;
  28.  
  29. public Latch(int limit) {
  30. this.limit = limit;
  31. }
  32.  
  33. //该方法会使得当前线程一致等待
  34. public abstract void await()throws InterruptedException;
  35.  
  36. //带超时功能的
  37. public abstract void await(TimeUnit unit, long time) throws InterruptedException,WaitTimeoutException;
  38.  
  39. //当任务线程完成工作之后调用该方法使得计数器减一
  40. public abstract void countDown();
  41.  
  42. //获取当前还有多少个线程没有完成任务
  43. public abstract int getUnarrived();
  44. }
  45.  
  46. //无限等待CountDownLatch实现
  47. class CountDownLatch extends Latch{
  48.  
  49. public CountDownLatch(int limit) {
  50. super(limit);
  51. }
  52.  
  53. @Override
  54. public void await() throws InterruptedException {
  55. synchronized (this) {
  56. while (limit > 0) {
  57. this.wait();
  58. }
  59. }
  60. }
  61.  
  62. /*
  63. 这个写法在写改写sysn时用过了。
  64. */
  65. @Override
  66. public void await(TimeUnit unit, long time) throws InterruptedException, WaitTimeoutException {
  67. if (time < 0) {
  68. throw new IllegalArgumentException("The time is invalid.");
  69. }
  70.  
  71. long remainingNanos = unit.toNanos(time);
  72.  
  73. final long endNanos = System.nanoTime()+ remainingNanos;
  74. synchronized (this) {
  75. while (limit > 0) {
  76. if (TimeUnit.NANOSECONDS.toMillis(remainingNanos) <= 0) {
  77. throw new WaitTimeoutException("The wait time over specify time.");
  78. }
  79.  
  80. this.wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos));
  81. remainingNanos=endNanos-System.nanoTime();
  82. }
  83. }
  84. }
  85.  
  86. @Override
  87. public void countDown() {
  88. synchronized (this) {
  89. if (limit <= 0) {
  90. throw new IllegalArgumentException("all of task already arrived");
  91. }
  92. limit--;
  93. this.notifyAll();
  94. }
  95. }
  96.  
  97. @Override
  98. public int getUnarrived() {
  99. return limit;
  100. }
  101. }
  102.  
  103. //程序测试齐心协力打开门阀
  104. class ProgrammerTravle extends Thread{
  105. private final Latch latch;
  106. private final String programmer;
  107. private final String transportation;
  108.  
  109. public ProgrammerTravle(Latch latch, String programmer, String transportation) {
  110. this.latch = latch;
  111. this.programmer = programmer;
  112. this.transportation = transportation;
  113. }
  114.  
  115. @Override
  116. public void run() {
  117. System.out.println(programmer+" start take the transportation["+transportation+"]");
  118. try{
  119. TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(10));
  120. } catch (InterruptedException e) {
  121. e.printStackTrace();
  122. }
  123. System.out.println(programmer+" arrived by "+transportation);
  124. latch.countDown();
  125. }
  126. }
  127.  
  128. class ProgrammerTravleTest{
  129. public static void test(){
  130. Latch latch = new CountDownLatch(4);
  131. new ProgrammerTravle(latch,"A","a").start();
  132. new ProgrammerTravle(latch,"B","b").start();
  133. new ProgrammerTravle(latch,"C","c").start();
  134. new ProgrammerTravle(latch,"D","d").start();
  135.  
  136. try {
  137. latch.await();
  138. System.out.println("==all of programmer arrived==");
  139. } catch (InterruptedException e) {
  140. e.printStackTrace();
  141. }
  142. }
  143. public static void test2(){
  144. Latch latch = new CountDownLatch(4);
  145. new ProgrammerTravle(latch,"A","a").start();
  146. new ProgrammerTravle(latch,"B","b").start();
  147. new ProgrammerTravle(latch,"C","c").start();
  148. new ProgrammerTravle(latch,"D","d").start();
  149.  
  150. try {
  151. latch.await(TimeUnit.SECONDS,5);
  152. System.out.println("==all of programmer arrived==");
  153. } catch (InterruptedException e) {
  154. e.printStackTrace();
  155. } catch (WaitTimeoutException e) {
  156. e.printStackTrace();
  157. }
  158. }
  159. }

《Java高并发编程详解》笔记

Latch设计模式的更多相关文章

  1. Android开发中常见的设计模式

    对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的 ...

  2. Spring源码分析 之浅谈设计模式

    一直想专门写个Spring源码的博客,工作了,可以全身性的投入到互联网行业中.虽然加班很严重,但是依然很开心.趁着凌晨有时间,总结总结. 首先spring,相信大家都很熟悉了. 1.轻量级  零配置, ...

  3. 转 多线程 闭锁(Latch) 栅栏(CyclicBarrier)

    java多线程并发系列之闭锁(Latch)和栅栏(CyclicBarrier) 标签: java并发编程 2015-05-28 16:45 2939人阅读 评论(0) 收藏 举报 本文章已收录于: . ...

  4. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  5. java EE设计模式简介

    1.何为设计模式 设计模式提供了对常见应用设计问题的解决方案.在面向对象的编程中,设计模式通常在解决与对象创建和交互相关的问题,而非整体软件架构所面对的大规模问题,它们以样板代码的形式提供了通用的解决 ...

  6. 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式

    上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...

  7. 《JavaScript设计模式 张》整理

    最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...

  8. 《JavaScript设计模式与开发实践》整理

    最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...

  9. 设计模式之行为类模式大PK

                                        行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...

随机推荐

  1. 微信小程序把玩(三十四)Audio API

    原文:微信小程序把玩(三十四)Audio API 没啥可值得太注意的地方 重要属性: 1. wx.getBackgroundAudioPlayerState(object) 获取播放状态 2.wx.p ...

  2. Cannot read property 'substring' of undefined

    这个是在使用 jquery的ztree插件过程中遇到的错误 原因是数据的格式和规定的格式不一致,需要把数据按照模板给的样子来

  3. 【Windows10 IoT开发系列】Powershell命令行实用程序

    原文:[Windows10 IoT开发系列]Powershell命令行实用程序 更新帐户密码: 强烈建议你更新默认的管理员帐户密码.若要更新帐户密码,你可以发出以下命令: net user Admin ...

  4. Android零基础入门第63节:过时但仍值得学习的选项卡TabHost

    原文:Android零基础入门第63节:过时但仍值得学习的选项卡TabHost 由于前几天参加一个学习培训活动,几乎每天都要从早晨7点到晚上一两点,没有什么时间来分享,实在抱歉中间断更了几天.从今天开 ...

  5. extjs grid 复选框选择事件

    开发中需求是统计选择的行数,所以要监控checkbox的选择事件包括表头的全选事件 遇到的问题就不赘述了 方案是监控grid的复选框和行加载时绑定事件 baseView: DBEN.controls. ...

  6. EF CodeFirst数据迁移与防数据库删除

    1 开启migrations功能 enable-migrations -force 2 添加迁移版本 add-migration 名称后缀 我们每次修改实体后,都应该使用这个add-migration ...

  7. 利用AngularJS实现一个单页应用

    看了下angular 的route,用它做个非常简单的单页面应用,记录一下. 顺便说下,好处是,页面改变时不需要刷新,而每个页面都展现不同的数据.尤其在使用模板页的时候,非常方便. 快速使用Roman ...

  8. Cocos2d-x 3.X Qt MinGW版本编译运行

    自Cocos2d-x 3.X引入了C++ 11特性,在Windows平台上的支持就仅限VS 2012,其实还可以尝试MinGW版本,GitHub上有MinGW版本的Qt Creator工程. 地址:h ...

  9. 第一个SpringBoot测试实例

    1.SpringBoot项目构建:http://start-spring.io   自动化构建SpringBoot项目,保存在本地并解压 2.安装gradle并配置gradle环境 3.配置阿里云ma ...

  10. postman --- 如何在用户登陆和CSRF验证的场景下使用

    一.前提 安装postman和Postman Interceptor postman应用放到桌面: 二.用户登陆 这种场景很简单,只要开启Interceptor,然后先请求登陆地址,再继续请求其他地址 ...