并发是个什么鬼之同步工具类CountDownLatch
扯淡
写这篇文章,我先酝酿一下,实不相瞒,脱离底层太久了,更确切的情况是,真没曾认真研究过。就目前来说,很多框架包括工具类已经把实现封装的很深,你只需轻轻的调用一下API,便不费半点力气。以至于大家会产生种种错觉,开发无非如此,总觉得混个三五年,也能混上CTO,迎娶白富美,当然这毕竟是少数。
我觉的大多数开发者的困惑是,底层的东西即使深入了解,如果不是BAT这种重研发型,自造血的公司,对于目前的工作亦或者将来的工作可能并没有什么用武之地。
正题
CountDownLatch 又是大神 Doug Lea的又一神作,正如每个Java文档所描述的那样,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

源码分析
源码位于rt.java中的java.util.concurrent包中。
1、CountDownLatch:A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
中文解释:也就是说主线程在等待所有其它的子线程完成后再往下执行
2、构造函数:CountDownLatch(int count)//初始化count数目的同步计数器,只有当同步计数器为0,主线程才会向下执行
主要方法:void await()//当前线程等待计数器为0
boolean await(long timeout, TimeUnit unit)//与上面的方法不同,它加了一个时间限制。
void countDown()//计数器减1
long getCount()//获取计数器的值
3.它的内部有一个辅助的内部类:sync.
它的实现如下:
/**
* 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;
}
}
}
4.await()方法的实现
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
//调用3中的tryAcquireShared()方法
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);//加入到等待队列中
}
5.countDown()方法的实现
public void countDown() {
sync.releaseShared(1);
}
public final boolean releaseShared(int arg) {
//调用3中的tryReleaseShared()方法
if (tryReleaseShared(arg)) {
//解锁
doReleaseShared();
return true;
}
return false;
}
应用场景
比如主任务是一个比较复杂的运算,为了节约时间,我们可以拆分成多个子任务,多线程同时执行,最终统一汇总任务。
其实生活也有类似的场景,比如马拉松赛跑,我们不可能按顺序依次跑步,这样得跑到猴年马月。一般来说都是大家听到发号命令一起跑,最终比赛结束,统一汇总成绩。
代码案例
下面看一个例子大家就清楚CountDownLatch的用法了:
/**
* CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待
* 构造方法参数指定了计数的次数
* countDown方法,当前线程结束执行后调用,计数减一
* awaint方法,调用此方法会一直阻塞当前线程,直到计时器的值为0
* 创建者 科帮网
* 创建时间 2017年8月15日
*
*/
public class CountDownLatchDemo {
final static SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
final static String startTime = sdf.format(new Date());
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(2);// 两个赛跑者
Runer runer1 = new Runer("刘翔", 5000, latch);
Runer runer2 = new Runer("罗伯斯", 8000, latch);
runer1.start();//刘翔 开始跑步
runer2.start();//罗伯斯 开始跑步
latch.await();// 等待所有人赛跑结束
System.out.println("all runer done at " + sdf.format(new Date()));
}
static class Runer extends Thread {
String runerName;
int runTime;
CountDownLatch latch;
public Runer(String runerName, int runTime, CountDownLatch latch) {
this.runerName = runerName;
this.runTime = runTime;
this.latch = latch;
}
public void run() {
System.out.println("Runer " + runerName + " do run begin at "
+ startTime);
doRun();//跑步
System.out.println("Runer " + runerName + " do run complete at "
+ sdf.format(new Date()));
latch.countDown();// 终点结束,计数器减一
}
private void doRun() {
try {
Thread.sleep(runTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
并发是个什么鬼之同步工具类CountDownLatch的更多相关文章
- 同步工具类 CountDownLatch 和 CyclicBarrier
在开发中,一些异步操作会明显加快执行速度带来更好的体验,但同时也增加了开发的复杂度,想了用好多线程,就必须从这些方面去了解 线程的 wait() notify() notifyall() 方法 线程异 ...
- 同步工具类—— CountDownLatch
本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 CountDownLatch简介 CountDownLa ...
- JUC常用同步工具类——CountDownLatch,CyclicBarrier,Semaphore
在 JUC 下包含了一些常用的同步工具类,今天就来详细介绍一下,CountDownLatch,CyclicBarrier,Semaphore 的使用方法以及它们之间的区别. 一.CountDownLa ...
- 并发包下常见的同步工具类(CountDownLatch,CyclicBarrier,Semaphore)
在实际开发中,碰上CPU密集且执行时间非常耗时的任务,通常我们会选择将该任务进行分割,以多线程方式同时执行若干个子任务,等这些子任务都执行完后再将所得的结果进行合并.这正是著名的map-reduce思 ...
- 深入分析同步工具类之AbstractQueuedSynchronizer
概览: AQS(简称)依赖内部维护的一个FIFO(先进先出)队列,可以很好的实现阻塞.同步:volatile修饰的属性state,哪个线程先改变这个状态值,那么这个线程就获得了优先权,可以做任何事 ...
- 《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&并发容器类&同步工具类,消费者模式
上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Has ...
- Java并发(基础知识)——显示锁和同步工具类
显示锁 Lock接口是Java ...
- Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger
在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...
- java 利用同步工具类控制线程
前言 参考来源:<java并发编程实战> 同步工具类:根据工具类的自身状态来协调线程的控制流.通过同步工具类,来协调线程之间的行为. 可见性:在多线程环境下,当某个属性被其他线程修改后,其 ...
随机推荐
- Qt中使用CEF(Windows下)
最近项目中要在Qt中使用CEF(Chromium Embedded Framework),在这里总结下其中的几个要点. 下载合适的CEF版本 关于CEF的简介我们这里就不做介绍了,下载CEF可以有2种 ...
- bzoj2038: [2009国家集训队]小Z的袜子(hose) [莫队]
Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜 ...
- Jenkins2 实现持续交付初次演练(MultiJob,Pipeline,Blue Ocean)
背景 项目需要用到自动部署,但可获取外网的节点机器只有一台,那只能同过主节点机器进行构建完成然后分发至对应服务器进行启动更新. 目前已尝试过三种方式: 1.Pipeline-Trigger param ...
- Linux通过shell执行自动化部署
背景 通过shell判断是否存在补丁更新,进行自动化的部署 代码 #!/bin/sh #Edit:何彦霆 #version: beta #执行环境初始化 source /hxspace/product ...
- 2017年7月Web服务器调查报告
在2017年7月的调查中,我们收到了来自1,767,964,429个网站和6,593,508个面向web的计算机的反馈.这是一个小小的进步,网站的数量增加了100万个(+0.06%),面向web的计算 ...
- (转)Sublime Text2 快捷键汇总
场景:最近在编写项目中越发的感觉到一个得心应手的编辑器是多么的重要,而sublime,无疑是让我用着最舒服,最有感觉的编辑器了! 1 快捷键总结 一个好的编辑器,能大大提高编程的效率.如果能熟知软件的 ...
- scanf返回值问题
在家养病,闲着没事看C primer plus,看到书中对于scanf输入的判断,常用如下方法: 此时它将返回1视为我输入成功,如果不为1则视为输入失败.那到底scanf的返回值具体指的是什么呢? 例 ...
- 【原创】01-1. 基于 checked 关于 attribute 和 property 的理解
Attribute(属性) 和 Property(特性) Attribute(元素节点的属性),例如html中常用的class.title.align等(即:属性节点).而Property 是这个DO ...
- log4g 使用教程
日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录.在apache网站:jakarta.apache.org/log4j 可以免费下载到Log ...
- ps-ef|grep-vgrep|grepsep|awk'{print"kill-9"$2}'|sh 这个表达式到底是什么意思啊?
最佳答案 kill 掉sep这个程序ps -ef | 获取当前服务器所有进程grep -v grep 相当于grep自己吧自己过滤掉,就是不显示grepgrep seq 过滤出seqawk 截取 ...