CountDownLatch的中文翻译为"闭锁",在JDK1.5中 CountDownLatch类加入进来。为程序猿进行并发编程提供有利的帮助。

首先我们先看看JDK文档中对于CountDownLatch类的介绍:

  1. A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
  1.  大致意思是CountDownLatch为一个同步辅助工具,让一个或多个线程等待,直到其他的线程执行操作完成。

  它的功能可以在绝大部分情况上替代join()方法,甚至在实际运用中比join()方法的用法更灵活。

  操作过程:用CountDownLatch类创建实例,指定需要等待完成点个数。await()方法会阻塞当前线程,直到计数器减为零。每次线程执行调用countDown()方法,就会使计数器减1,直到计数器减为0时,等待的线程继续运行。

  • CountDownLatch类中的构造器:
  1. /**
  2. * Constructs a {@code CountDownLatch} initialized with the given count.
  3. *
  4. * @param count the number of times {@link #countDown} must be invoked
  5. * before threads can pass through {@link #await}
  6. * @throws IllegalArgumentException if {@code count} is negative
       * 构造器用给定计数作为参数进行初始化,若参数为负则抛出非法参数异常。
       *
  7. */
  8. public CountDownLatch(int count) {
  9. if (count < 0) throw new IllegalArgumentException("count < 0");
  10. this.sync = new Sync(count);
  11. }
  • CountDownLatch类中的方法:

  1. await() 方法

  1. /**
  2. * Causes the current thread to wait until the latch has counted down to
  3. * zero, unless the thread is {@linkplain Thread#interrupt interrupted}.
  4. * 使当前线程等待直到闭锁的计数器为0,除非线程由于中断异常中断。
  5. */
  6. public void await() throws InterruptedException {
  7. sync.acquireSharedInterruptibly(1);
  8. }

  2. await(long timeout, TimeUnit unit) 方法

  1. /**
  2. * Causes the current thread to wait until the latch has counted down to
  3. * zero, unless the thread is {@linkplain Thread#interrupt interrupted},
  4. * or the specified waiting time elapses.
       * 使当前线程等待直到闭锁计数器为0,除非线程遇到线程中断异常中断,或者超出指定的等待时间。
  5. * @param timeout the maximum time to wait 超出的最大等待时间
  6. * @param unit the time unit of the {@code timeout} argument 指定最大等待时间的时间单位
  7. * @return {@code true} if the count reached zero and {@code false}
  8. * if the waiting time elapsed before the count reached zero
  9. * @throws InterruptedException if the current thread is interrupted
  10. * while waiting
  11. */
  12. public boolean await(long timeout, TimeUnit unit)
  13. throws InterruptedException {
  14. return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
  15. }

  3. countDown() 方法

  1. /**
  2. * Decrements the count of the latch, releasing all waiting threads if
  3. * the count reaches zero.
  4. * 减少闭锁的计数,若计数达到0则释放所有等待线程
  5. * <p>If the current count is greater than zero then it is decremented.
  6. * If the new count is zero then all waiting threads are re-enabled for
  7. * thread scheduling purposes.
  8. *
  9. * <p>If the current count equals zero then nothing happens.
  10. */
  11. public void countDown() {
  12. sync.releaseShared(1);
  13. }

  4. getCount() 方法

  1. /**
  2. * Returns the current count.
  3. * 返回当前计数器的值
  4. * <p>This method is typically used for debugging and testing purposes.
  5. *
  6. * @return the current count
  7. */
  8. public long getCount() {
  9. return sync.getCount();
  10. }

应用:

  有这么一道题:用4个线程并发执行从1加到100,每个线程只能加25个数,主线程需要等待子线程结束完成后才能结束。

  思想:可以用join()方法,也可以用CountDownLatch对象来暂停主线程。

  代码:

  1. import java.util.concurrent.CountDownLatch;
  2.  
  3. public class Compute {
  4. public static int sum = 0;// 存储1加到100的数
  5. public static CountDownLatch count = new CountDownLatch(4);// 闭锁,计数器设置为4
  6.  
  7. static class ComputeThread extends Thread {// 内部类
  8. int start, end;// 起始与结束
  9.  
  10. public ComputeThread(int start, int end) {
  11. this.start = start;
  12. this.end = end;
  13. }
  14.  
  15. @Override
  16. public void run() {// 每个线程都进行累加
  17. for (int i = start; i <= end; i++) {
  18. sum += i;
  19. }
  20. System.out.println(currentThread().getName() + ":" + sum);
  21. count.countDown();
  22. }
  23. }
  24.  
  25. public static void main(String[] args) throws InterruptedException {
  26. // 建立4个线程
  27. ComputeThread c1 = new Compute.ComputeThread(1, 25);
  28. ComputeThread c2 = new Compute.ComputeThread(26, 50);
  29. ComputeThread c3 = new Compute.ComputeThread(51, 75);
  30. ComputeThread c4 = new Compute.ComputeThread(76, 100);
  31. // 启动4个线程
  32. c1.start();
  33. c2.start();
  34. c3.start();
  35. c4.start();
  36. // 让调用线程停止,等待计数器为0
  37. count.await();
  38. System.out.println(sum);
  39. }
  40. }
  1.  

对CountDownLatch的初步学习的更多相关文章

  1. json2.js的初步学习与了解

    json2.js的初步学习与了解,想要学习json的朋友可以参考下. json2.js的初步学习与了解 1.)该js的下载地址是:http://www.json.org/json2.js 2.)在页面 ...

  2. 老周的ABP框架系列教程 -》 一、框架理论初步学习

    老周的ABP框架系列教程 -- 一.框架理论初步学习   1. ABP框架的来源与作用简介 1.1  简介 1.1.1       ABP框架全称为"ASP.NET Boilerplate ...

  3. 初步学习nodejs,业余用node写个一个自动创建目录和文件的小脚本,希望对需要的人有所帮助

    初步学习nodejs,业余用node写个一个自动创建目录和文件的小脚本,希望对需要的人有所帮助,如果有bug或者更好的优化方案,也请批评与指正,谢谢,代码如下: var fs = require('f ...

  4. EF Codefirst 初步学习(二)—— 程序管理命令 更新数据库

    前提:搭建成功codefirst相关代码,参见EF Codefirst  初步学习(一)--设置codefirst开发模式 具体需要注意点如下: 1.确保实体类库程序生成成功 2.确保实体表类库不缺少 ...

  5. 初步学习python

    自计算机诞生以来,也伴随着计算机语言的诞生,现在,全世界的编程语言有600多种,但流行的编程语言也就20多种. Java和C一直占据着前两名.但是近年来伴随着人工智能的发展,Python发展迅猛,以其 ...

  6. Git的初步学习

    前言 感谢! 承蒙关照~ Git的初步学习 为什么要用Git和Github呢?它们的出现是为了用于提交项目和存储项目的,是一种很方便的项目管理软件和网址地址. 接下来看看,一家公司的基本流程图: 集中 ...

  7. 语法分析器初步学习——LISP语法分析

    语法分析器初步学习——LISP语法分析 本文参考自vczh的<如何手写语法分析器>. LISP的表达式是按照前缀的形式写的,比如(1+2)*(3+4)在LISP中会写成(*(+ 1 2)( ...

  8. 状态保持以及AJAX的初步学习

    嘿嘿,今天学习的有点迷茫哦,主要学习把验证码使用在登录页面时间的一些逻辑,学习这个时间并没有那么的迷惑哦,可是自己写程序时间倒是有点反应迟钝,不过还好总是在最后搞清楚啦,另外就是一步一步的学习是接近项 ...

  9. LinQ的初步学习与总结

    嘿嘿,说起来ORM和LinQ,就感觉离我好遥远的,在学校是没有学习的,所以总感觉学习了LinQ就是大神,现在嘛,终于也体会一点,感觉LinQ只是初步学习,没有太难,当然以后使用在项目中就没有这样的简单 ...

随机推荐

  1. jQuery的ID选择器失效问题

    jQuery的ID选择器,在同一项目别的文件中一切正常: 在当前页面,jQuery的其它功能(如:$(document).ready(function(){  alert("ok" ...

  2. 【转帖】Mysql多维数据仓库指南 第一篇 第1章

     Mysql多维数据仓库指南 第一篇基本原理 章节列表: 第1章:基本组成 第2章:维度历史 第3章:维度可加性 第4章:维度查询 本篇概述 你将运用关系数据库来实施一个维度数据仓库.事实表和维表这两 ...

  3. ORA-00001: unique constraint (...) violated并不一定是数据冲突

    原文链接:http://blog.163.com/jet_it_life/blog/static/205097083201301410303931/ 收到一位测试人员RAISE的JIRA,说在某张表上 ...

  4. spring扩展的常用接口

    一:ApplicationContextAware接口 实现ApplicationContextAware接口,重写setApplicationContext方法,可以将spring容器上下文对象注入 ...

  5. [TensorBoard] Name & Variable scope

    TF有两个scope, 一个是name_scope一个是variable_scope 第一个程序: with tf.name_scope("hello") as name_scop ...

  6. [Laravel] 03 - DB facade, Query builder & Eloquent ORM

    连接数据库 一.Outline 三种操作数据库的方式. 二.Facade(外观)模式 Ref: 解读Laravel,看PHP如何实现Facade? Facade本质上是一个“把工作推给别人做的”的类. ...

  7. postmain 通过函数动态设置参数

    调用服务器的服务,其中有个参数是签名,签名需要计算,需要写一个本地函数. 下一步 pre-request Script 的代码如下: (function($) { if(!$.encoding) $. ...

  8. lsass 病毒手动清除方法

    病毒症状进程里面有2个lsass.exe进程,一个是system的,一个是当前用户名的(该进程为病毒).双击D:盘打不开,只能通过右击选择打开来打开.用kaspersky扫描可以扫描出来,并且可以杀掉 ...

  9. POJ 2018 Best Cow Fences(二分+最大连续子段和)

    Best Cow Fences Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 14601 Accepted: 4720 Desc ...

  10. C++判断是否连接服务器

    BOOL CheckServerStatus::isConnectServer(CString serverName, int serverPort) { CString strURL; strURL ...