[笔记][Java7并发编程实战手冊]系列文件夹


简单介绍

本文学习CountDownLatch 倒计数闭锁。

本人英文不好。靠机器翻译,然后有一段非常形象的描写叙述,让我把它叫为倒计数

用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法。所以在当前计数到达零之前。await 方法会一直受堵塞。

之后,会释放全部等待的线程,await 的全部兴许调用都将马上返回。这样的现象仅仅出现一次——计数无法被重置。 - jdk1.6里面的文档

能够看出,是由于会倒计数。并且计数器到0之后, 就不能再次使用该对象了(自断后路)。所以称为倒计数闭锁


CountDownLatch

是一个同步辅助类,在完毕一组正在其它线程中执行的操作之前,它同意一个或多个线程一直等待。

假如说:有a、b、c 三个线程。c 须要a,b线程的结果,所以C 须要等待 a,b 线程都执行完了,b 才干拿到正确的结果。 就是该类的一个使用场景

  1. countDown() 来计数(计时)
  2. await() 创建屏障点。等待计数到0的时候,await()方法后面的代码才执行。(换句话说。计数线程一起冲破这个屏障)
  3. getCount(): 是获取当前计数,不是总数
  4. 是辅助类! 不保证同步。

原理:

CountDownLatch是通过“共享锁”实现的。

在创建CountDownLatch中时,会传递一个int类型參数count,该參数是“锁计数器”的初始状态。表示该“共享锁”最多能被count给线程同一时候获取。当某线程调用该CountDownLatch对象的await()方法时,该线程会等待“共享锁”可用时,才干获取“共享锁”进而继续执行。而“共享锁”可用的条件,就是“锁计数器”的值为0!而“锁计数器”的初始值为count,每当一个线程调用该CountDownLatch对象的countDown()方法时,才将“锁计数器”-1。通过这样的方式。必须有count个线程调用countDown()之后,“锁计数器”才为0,而前面提到的等待线程才干继续执行。


演示样例

场景:密室大门将在七颗龙珠都被镶嵌到大门上的机关上时,密室大门才会打开。

以下的演示样例:讲述了一个密室(线程)。和7个工匠(线程)镶嵌龙珠, 最后密室大门被打开,守卫(主线程)复活的故事

/**
* Created by zhuqiang on 2015/8/19 0019.
*/
public class Client {
public static void main(String[] args) {
final CountDownLatch cd = new CountDownLatch(7); //创建辅助类7个倒计数
final Adytum adytum = new Adytum(cd);
new Thread(adytum).start();
for (int i = 0; i < 7; i++) {
new Thread(new Runnable() {
@Override
public void run() {
adytum.inlay();
}
}).start();
} // 主线程 来模拟守卫吧。
try {
cd.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("守卫也复活了!");
} } //密室
class Adytum implements Runnable {
private CountDownLatch cd;
private long num = 7; // 记录剩余未被镶嵌的龙珠 ,用来对照和getCount返回的是否相等
private ReentrantLock lock = new ReentrantLock(); //创建同步锁。保证 inlay 中的资源计数 被正确计算。 public Adytum(CountDownLatch cd) {
this.cd = cd;
} // 为密室大门服务的线程
@Override
public void run() {
System.out.println("欢迎来到密室。密室正等待被打开...");
try {
cd.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("当前龙珠已镶嵌%d颗。密室被打开了!欢呼吧\n",num);
} /**
* 镶嵌龙珠到大门上
*/
public void inlay() {
try {
lock.lock(); // 把这里的锁去掉,能看到错误的计算数据,说明了CountDownLatch:不保证同步
long count = cd.getCount(); //返回当前还剩余计数
long time = (long) (Math.random() * 10); //模拟镶嵌了多少时间
System.out.printf("%s把龙珠镶嵌到了大门上,还有%d个龙珠未被镶嵌,计数是否和getCount相等:%s,此次镶嵌耗时:%d 秒\n", Thread.currentThread().getName(), count,count==num,time);
num--;
TimeUnit.SECONDS.sleep(time); //休眠辅助类。按指定单位休眠
cd.countDown(); //锁 保证是这个临界区内的代码同步。线程相互排斥,计算的结果正确被刷到主内存中。 不是说countDown方法须要来同步
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}

未加锁的某一次执行结果:

把 lock.lock(); 加锁相关的代码凝视掉。

欢迎来到密室。密室正等待被打开...
Thread-1把龙珠镶嵌到了大门上,还有7个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:5 秒
Thread-2把龙珠镶嵌到了大门上,还有7个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:2 秒
Thread-4把龙珠镶嵌到了大门上,还有7个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:0 秒
Thread-3把龙珠镶嵌到了大门上,还有7个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:1 秒
Thread-6把龙珠镶嵌到了大门上,还有7个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:7 秒
Thread-5把龙珠镶嵌到了大门上,还有7个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:9 秒
Thread-7把龙珠镶嵌到了大门上,还有7个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:0 秒
守卫也复活了!
当前龙珠已镶嵌0颗,密室被打开了!欢呼吧

说明:能看到错误的计算数据,全是还有7个龙珠。说明了CountDownLatch:不保证同步,仅仅是达到 让一个线程或则多个线程等待


加锁的正确结果

欢迎来到密室,密室正等待被打开...
Thread-1把龙珠镶嵌到了大门上,还有7个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:2 秒
Thread-2把龙珠镶嵌到了大门上,还有6个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:0 秒
Thread-3把龙珠镶嵌到了大门上,还有5个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:5 秒
Thread-4把龙珠镶嵌到了大门上,还有4个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:5 秒
Thread-5把龙珠镶嵌到了大门上,还有3个龙珠未被镶嵌。计数是否和getCount相等:true,此次镶嵌耗时:0 秒
Thread-6把龙珠镶嵌到了大门上,还有2个龙珠未被镶嵌。计数是否和getCount相等:true,此次镶嵌耗时:2 秒
Thread-7把龙珠镶嵌到了大门上,还有1个龙珠未被镶嵌,计数是否和getCount相等:true,此次镶嵌耗时:5 秒
当前龙珠已镶嵌0颗,密室被打开了!欢呼吧
守卫也复活了!

说明:有密室,和守卫两个线程等待7个工匠线程把龙珠镶嵌完毕后,密室被打开,守卫也复活,得到了我们想要的正确结果

[笔记][Java7并发编程实战手冊]3.4 等待多个并发事件的完毕CountDownLatch倒计数闭锁的更多相关文章

  1. [笔记][Java7并发编程实战手冊]系列文件夹

    推荐学习多线程之前要看的书. [笔记][思维导图]读深入理解JAVA内存模型整理的思维导图文章里面的思维导图或则相应的书籍.去看一遍. 能理解为什么并发编程就会出现故障. Java7并发编程实战手冊 ...

  2. [笔记][Java7并发编程实战手冊]3.8 并发任务间的数据交换Exchanger

    [笔记][Java7并发编程实战手冊]系列文件夹 简单介绍 Exchanger 是一个同步辅助类.用于两个并发线程之间在一个同步点进行数据交换. 同意两个线程在某一个点进行数据交换. 本章exchan ...

  3. 那些年读过的书《Java并发编程实战》一、构建线程安全类和并发应用程序的基础

    1.线程安全的本质和线程安全的定义 (1)线程安全的本质 并发环境中,当多个线程同时操作对象状态时,如果没有统一的状态访问同步或者协同机制,不同的线程调度方式和不同的线程执行次序就会产生不同的不正确的 ...

  4. 【Java并发编程实战】—–synchronized

    在我们的实际应用其中可能常常会遇到这样一个场景:多个线程读或者.写相同的数据,訪问相同的文件等等.对于这样的情况假设我们不加以控制,是非常easy导致错误的. 在java中,为了解决问题,引入临界区概 ...

  5. Java并发编程实战 05等待-通知机制和活跃性问题

    Java并发编程系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 Java并发编程实 ...

  6. 《Java7并发编程实战手册》读书笔记

    一.线程管理 1.线程的创建和运行 创建线程的2种方式: 继承Thread类,并覆盖run()方法 创建一个实现Runnable接口的类.使用带参数的Thread构造器来创建Thread对象 每个Ja ...

  7. 《Go并发编程实战》读书笔记-语法概览

    <Go并发编程实战>读书笔记-语法概览 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客我们会快速浏览一下Go的语法,内容涉及基本构成要素(比如标识符,关键字,子 ...

  8. 《Go并发编程实战》读书笔记-初识Go语言

    <Go并发编程实战>读书笔记-初识Go语言 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在讲解怎样用Go语言之前,我们先介绍Go语言的特性,基础概念和标准命令. 一. ...

  9. 《Java并发编程实战》读书笔记一 -- 简介

    <Java并发编程实战>读书笔记一 -- 简介 并发的历史 并发的历史,也是人类利用有限的资源去提高生产效率的一个的例子. 设想现在有台计算机,这台计算机具有以下的资源: 单核CPU一个 ...

随机推荐

  1. 略过天涯 深入浅出VGA和DVI接口【转】

    本文转载自:http://www.cnblogs.com/lueguo/p/3373649.html 由CrazyBingo修改…… 前言:目前显示器的主流接口是VGA.DVI以及HDMI,再加上一个 ...

  2. Cache操作类

    封装类: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sys ...

  3. 分布式系统CAP原则与BASE思想

    一.CAP原则 CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性). Availability(可用性).Partition tolerance(分区容错性),三者 ...

  4. 【转】不要使用SBJSON(json-framework)

    原文网址:http://blog.devtang.com/2012/05/05/do-not-use-sbjson/ 不知道为什么,在iOS开发中,有很多人使用 SBJSON (又被称作json-fr ...

  5. leetcode 几道题目

    是周六晚上的几道题,晚上11点半,睡的早,起不来! 494. Target Sum 分析:看完这题,看到数据范围,长度20,枚举就是1<<20 = 1e6, 然后单次20,总共就是2e8, ...

  6. Tomcatsession共享方案--memcached-session-manager

    https://github.com/magro/memcached-session-manager/wiki/SerializationStrategies     MSM的特性:    a.支持t ...

  7. P3399 丝绸之路

    题目背景 张骞于公元前138年曾历尽艰险出使过西域.加强了汉朝与西域各国的友好往来.从那以后,一队队骆驼商队在这漫长的商贸大道上行进,他们越过崇山峻岭,将中国的先进技术带向中亚.西亚和欧洲,将那里的香 ...

  8. JavaScript实现鼠标效果

    <html> <head> <meta charset="utf-8"> <title>无标题文档</title> &l ...

  9. (转)webpack从零开始第6课:在Vue开发中使用webpack

    vue官方已经写好一个vue-webpack模板vue_cli,原本自己写一个,发现官方写得已经够好了,自己写显得有点多余,但为了让大家熟悉webpack,决定还是一步一步从0开始写,但源文件就直接拷 ...

  10. Spring学习笔记之依赖的注解(2)

    Spring学习笔记之依赖的注解(2) 1.0 注解,不能单独存在,是Java中的一种类型 1.1 写注解 1.2 注解反射 2.0 spring的注解 spring的 @Controller@Com ...