解读java同步类CountDownLatch
同步辅助类:
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的更多相关文章
- Java多线程信号量同步类CountDownLatch与Semaphore
信号量同步是指在不同线程之间,通过传递同步信号量来协调线程执行的先后次序.CountDownLatch是基于时间维度的Semaphore则是基于信号维度的. 1:基于执行时间的同步类CountDown ...
- Java中多线程同步类 CountDownLatch
在多线程开发中,常常遇到希望一组线程完成之后在执行之后的操作,java提供了一个多线程同步辅助类,可以完成此类需求: 类中常见的方法: 其中构造方法:CountDownLatch(int count) ...
- java中的线程(4):常用同步类 CountDownLatch、CyclicBarrier和Semaphore
转自: http://www.cnblogs.com/dolphin0520/p/3920397.html 1.简介 CountDownLatch和CyclicBarrier都能够实现线程之间的等待, ...
- Java并发之CountDownLatch 多功能同步工具类
package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * CountD ...
- 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore
前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...
- java 并发工具类CountDownLatch & CyclicBarrier
一起在java1.5被引入的并发工具类还有CountDownLatch.CyclicBarrier.Semaphore.ConcurrentHashMap和BlockingQueue,它们都存在于ja ...
- Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析
1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...
- Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger
在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...
- Java并发和多线程4:使用通用同步工具CountDownLatch实现线程等待
CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown ...
随机推荐
- webpack教程(二)——webpack.config.js文件
首先我们需要安装一个webpack插件html-webpack-plugin,该插件的作用是帮助我们生成创建html入口文件.执行如下命令 npm install html-webpack-plugi ...
- Oracle数据库中的重要对象
数据库中的重要对象:表.视图.序列.函数.存储过程.索引.同义词1.表:用PL/SQL Developer 软件打开 Scott的DEPT表查看SQL,可以看见DEPT表创建的脚本-- Create ...
- 最近学习java时的记录
1.java 的变量一共分为三种,类变量,局部变量,成员变量 类变量就是 加static修饰符的变量 2.java 的修饰符可分为两大类,一 可访问修饰符 protected private publ ...
- gulp实用配置(2)——中小项目
上一篇的gulp配置很简单,主要就是为了demo的查看和调试,这一篇则会相对详细一些,包括压缩合并打时间戳等. 在互联网环境比较好的城市,需要多人协作的,大一点的项目应该都用上了模块化(这里主要指co ...
- pgsql 递归查询 分页
--向下查询 WITH RECURSIVE res AS ( union ALL SELECT t_tree.* FROM t_tree, res WHERE t_tree.pid = res.id ...
- requirejs 加载其它js
基本代码: require.config({ // baseUrl : '/js/' paths: { jquery: '/js/jquery-1.11.3.min', validate: '/js/ ...
- CJOJ 1131 机器分配 / Luogu 2066 机器分配 (动态规划)
CJOJ 1131 机器分配 / Luogu 2066 机器分配 (动态规划) Description Luogu: 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国 ...
- 用java调用oracle存储过程总结
以前一直没有动存储过程是用来干嘛的,后来请教朋友才换为自己的理解方式,用自己通俗的语言来说,就是把sql语句换为一个过程,也可以说是一个方法,每次直接给参数调用就好,使用存储过程查询速度快,系统只编译 ...
- Java List Remove时要注意的细节
1.如果你是在遍历的时候去remove一个对象 for(int i = 0, length = list.size(); i<length; i++){} 这种遍历需要每次remove时,对i- ...
- Python爬虫番外篇之Cookie和Session
关于cookie和session估计很多程序员面试的时候都会被问到,这两个概念在写web以及爬虫中都会涉及,并且两者可能很多人直接回答也不好说的特别清楚,所以整理这样一篇文章,也帮助自己加深理解 什么 ...