同步辅助类:

CountDownLatch是一个同步辅助类,在jdk5中引入,它允许一个或多个线程等待其他线程操作完成之后才执行。

实现原理 :

CountDownLatch是通过计数器的方式来实现,计数器的初始值为线程的数量。每当一个线程完成了自己的任务之后,就会对计数器减1,当计数器的值为0时,表示所有线程完成了任务,此时等待在闭锁上的线程才继续执行,从而达到等待其他线程完成任务之后才继续执行的目的。

CountDownLatch主要方法:

CountDownLatch具体是通过同步器来实现的,使用AQS状态来表示计数:

    /**
* Synchronization control For CountDownLatch.
* Uses AQS state to represent count.
*/
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L; Sync(int count) {
setState(count);
} int getCount() {
return getState();
} protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
} protected boolean tryReleaseShared(int releases) {
// Decrement count; signal when transition to zero
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
} private final Sync sync;

  

1、构造函数

    public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}

通过传入一个数值来创建一个CountDownLatch,数值表示线程可以从等待状态恢复,countDown方法必须被调用的次数

2、countDown方法

public void countDown() {
sync.releaseShared(1);
}  

线程调用此方法对count进行减1。当count本来就为0,此方法不做任何操作,当count比0大,调用此方法进行减1,当new count为0,释放所有等待当线程。

3、await方法

(1)不带参数

    public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}

调用此方法时,当count为0,直接返回true,当count比0大,线程会一直等待,直到count的值变为0,或者线程被中断(interepted,此时会抛出中断异常)。

(2)带参数

    public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}

调用此方法时,当count为0,直接返回true,当count比0大,线程会等待一段时间,等待时间内如果count的值变为0,返回true;当超出等待时间,返回false;或者等待时间内线程被中断,此时会抛出中断异常。

CountDownLatch实践

司机和工人,工人必须等到司机来了才能装货上车,司机必须得等到所有工人把货物装上车了之后才能把车开走。

工人类:

public class Worker implements Runnable {

    private String workerCode;

    private CountDownLatch startLatch;
private CountDownLatch latch; Worker(CountDownLatch startLatch, CountDownLatch latch, String workerCode) {
this.startLatch = startLatch;
this.latch = latch;
this.workerCode = workerCode;
} public void run() {
try {
startLatch.await();
doWork();
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
} private void doWork() {
System.out.println("Worker " + workerCode + " is loading goods...");
}
}

司机类:

public class Driver {
public static void main(String[] args) throws InterruptedException {
CountDownLatch startLatch = new CountDownLatch(1);
CountDownLatch latch = new CountDownLatch(10);
ExecutorService executor = Executors.newFixedThreadPool(10); for(int i=0; i<10; i++) {
executor.execute(new Worker(startLatch, latch, "worker" + i));
} System.out.println("Driver is here."); startLatch.countDown(); System.out.println("Workers get to work."); latch.await(); System.out.println("Driver is ready to go."); executor.shutdown();
}
}  

运行结果:

Driver is here.
Workers get to work.
Worker worker0 is loading goods...
Worker worker1 is loading goods...
Worker worker2 is loading goods...
Worker worker3 is loading goods...
Worker worker4 is loading goods...
Worker worker5 is loading goods...
Worker worker7 is loading goods...
Worker worker9 is loading goods...
Worker worker8 is loading goods...
Worker worker6 is loading goods...
Driver is ready to go.

完整工程代码请参考git:https://github.com/xuweijian/CountDownLatch.git

解读java同步类CountDownLatch的更多相关文章

  1. Java多线程信号量同步类CountDownLatch与Semaphore

    信号量同步是指在不同线程之间,通过传递同步信号量来协调线程执行的先后次序.CountDownLatch是基于时间维度的Semaphore则是基于信号维度的. 1:基于执行时间的同步类CountDown ...

  2. Java中多线程同步类 CountDownLatch

    在多线程开发中,常常遇到希望一组线程完成之后在执行之后的操作,java提供了一个多线程同步辅助类,可以完成此类需求: 类中常见的方法: 其中构造方法:CountDownLatch(int count) ...

  3. java中的线程(4):常用同步类 CountDownLatch、CyclicBarrier和Semaphore

    转自: http://www.cnblogs.com/dolphin0520/p/3920397.html 1.简介 CountDownLatch和CyclicBarrier都能够实现线程之间的等待, ...

  4. Java并发之CountDownLatch 多功能同步工具类

    package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * CountD ...

  5. 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore

    前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...

  6. java 并发工具类CountDownLatch & CyclicBarrier

    一起在java1.5被引入的并发工具类还有CountDownLatch.CyclicBarrier.Semaphore.ConcurrentHashMap和BlockingQueue,它们都存在于ja ...

  7. Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析

    1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...

  8. Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger

    在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...

  9. Java并发和多线程4:使用通用同步工具CountDownLatch实现线程等待

    CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown ...

随机推荐

  1. Java泛型概念

    1. 概述在引入范型之前,Java类型分为原始类型.复杂类型,其中复杂类型分为数组和类.引入范型后,一个复杂类型就可以在细分成更多的类型.例如原先的类型List,现在在细分成List<Objec ...

  2. 怎样把echarts图表做成响应式的

    如果想要把echarts图表给做成响应式的那么就应该用rem 单位,给图表的外围容器设置rem 单位,然后调用jquery 的resize方法,$(window).resize(function(){ ...

  3. English - 被动语态的翻译原则

    被动语态翻译原则 1. Passive ----> Active The bag is stolen by him. One the whole, such a conclusion can b ...

  4. win7下elasticsearch5.0 安装head插件

    项目开发用到了ES,5.X版本的,然而网上好多的安装资料都不能用,全是之前的老版本,今天弄了一上午终于完事了,总结一下安装的步骤. 1.安装NodeJs 去官网https://nodejs.org/e ...

  5. 【Data Visual】一文搞懂matplotlib数据可视化

    一文搞懂matplotlib数据可视化 作者:白宁超 2017年7月19日09:09:07 摘要:数据可视化主要旨在借助于图形化手段,清晰有效地传达与沟通信息.但是,这并不就意味着数据可视化就一定因为 ...

  6. 常用http响应报文分析

    这是我在使用Asp.Net的时候,整理的的一些关于Http响应报文的分析笔记,零零散散的记录, 现在贴出来,抛砖引玉,如果有什么不对或者不严谨的地方,请各位大神不吝赐教. 一.HTTP响应码响应码由三 ...

  7. firefox插件开发及源码下载

    在个别情况下,由于数据量巨大,造成显示性能的明显下降,此时使用c++开发firefox插件,可以提高用户使用体验. test.html: 在插件中,我们导出3个函数给js:AddStr, Pause, ...

  8. ArrayList和LinkedList源码

    1 ArrayList 1.1 父类 java.lang.Object 继承者 java.util.AbstractCollection<E> 继承者 java.util.Abstract ...

  9. JMeter 之Synchronizing Timer运行原理

    JMeter测试并发场景,是通过设置Synchronizing Timer(同步定时器),熟悉LoadRunner性能测试的话,就知道里面有个概念:集合点. Synchronizing Timer则可 ...

  10. 二.GC相关之Java内存模型

    根据上节描述的问题,我们知道其最终原因是GC导致的.本节我们就先详细探讨下与GC息息相关的Java内存模型. 名词解释:变量,理解为java的基本类型.对象,理解为java new出来的实例. Jav ...