扯淡

写这篇文章,我先酝酿一下,实不相瞒,脱离底层太久了,更确切的情况是,真没曾认真研究过。就目前来说,很多框架包括工具类已经把实现封装的很深,你只需轻轻的调用一下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的更多相关文章

  1. 同步工具类 CountDownLatch 和 CyclicBarrier

    在开发中,一些异步操作会明显加快执行速度带来更好的体验,但同时也增加了开发的复杂度,想了用好多线程,就必须从这些方面去了解 线程的 wait() notify() notifyall() 方法 线程异 ...

  2. 同步工具类—— CountDownLatch

    本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 CountDownLatch简介 CountDownLa ...

  3. JUC常用同步工具类——CountDownLatch,CyclicBarrier,Semaphore

    在 JUC 下包含了一些常用的同步工具类,今天就来详细介绍一下,CountDownLatch,CyclicBarrier,Semaphore 的使用方法以及它们之间的区别. 一.CountDownLa ...

  4. 并发包下常见的同步工具类(CountDownLatch,CyclicBarrier,Semaphore)

    在实际开发中,碰上CPU密集且执行时间非常耗时的任务,通常我们会选择将该任务进行分割,以多线程方式同时执行若干个子任务,等这些子任务都执行完后再将所得的结果进行合并.这正是著名的map-reduce思 ...

  5. 深入分析同步工具类之AbstractQueuedSynchronizer

      概览: AQS(简称)依赖内部维护的一个FIFO(先进先出)队列,可以很好的实现阻塞.同步:volatile修饰的属性state,哪个线程先改变这个状态值,那么这个线程就获得了优先权,可以做任何事 ...

  6. 《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&并发容器类&同步工具类,消费者模式

    上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Has ...

  7. Java并发(基础知识)——显示锁和同步工具类

    显示锁                                                                                     Lock接口是Java ...

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

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

  9. java 利用同步工具类控制线程

    前言 参考来源:<java并发编程实战> 同步工具类:根据工具类的自身状态来协调线程的控制流.通过同步工具类,来协调线程之间的行为. 可见性:在多线程环境下,当某个属性被其他线程修改后,其 ...

随机推荐

  1. 函数响应式编程及ReactiveObjC学习笔记 (二)

    之前我们初步认识了RAC的设计思路跟实现方式, 现在我们再来看看如果使用它以及它能帮我们做什么 One of the major advantages of RAC is that it provid ...

  2. android 7.0 多渠道打包 - 美团开源工具Walle 命令行打包

    在Android 7.0(Nougat)推出了新的应用签名方案APK Signature Scheme v2后,之前快速生成渠道包的方式(美团Android自动化之旅-生成渠道包)已经行不通了,对此美 ...

  3. THINKPHP 3.2 PHP SFTP上传下载 代码实现方法

     一.SFTP介绍:使用SSH协议进行FTP传输的协议叫SFTP(安全文件传输)Sftp和Ftp都是文件传输协议.区别:sftp是ssh内含的协议(ssh是加密的telnet协议),  只要sshd服 ...

  4. 配置PLSQL,提升工作效率

    界面模板的配置: 方便用户快速点击需要的功能.如打开SQL Window 1.打开customize,用户自定义Toolbars对话框. 2.在Commands命令标签页,选中要添加的命令,拖动到工具 ...

  5. 基于.net的微服务架构的开发测试环境运维实践

    眼下,做互联网应用,最火的架构是微服务,最热的研发管理就是DevOps, 没有之一.微服务.DevOps已经被大量应用,它们已经像传说中的那样,可以无所不能.特来电云平台,通过近两年多的实践,发现完全 ...

  6. H5微信通过百度地图API实现导航方式二

    要有服务器才行哦 <!DOCTYPE html><html><head>    <meta http-equiv="Content-Type&quo ...

  7. 花了一年时间完成的 在线G代码编辑,加工系统 G-Code Editor V1.0

    G代码是数控程序中的加工指令.一般都称为G指令.可以直接用来驱动机床,各种控制系统.是一种数控行业标准.传统的G代码编写以及编辑无法在线编辑,也不能实时看到g代码编辑的最后加工路径已经不能直接对编辑的 ...

  8. ORACLE - 管理控制文件

    在oracle中,控制文件极其重要,如果该文件损坏并在没有备份的情况下,数据库将无法启动,里面的数据也将无法读取恢复,一般情况下,对数据库配置好了以后备份控制文件: 1. 查看控制文件 SQL> ...

  9. 自定义Git

    在安装Git一节中,我们已经配置了user.name和user.email,实际上,Git还有很多可配置项. 比如,让Git显示颜色,会让命令输出看起来更醒目: $ git config --glob ...

  10. ABP+AdminLTE+Bootstrap Table权限管理系统第三节--abp分层体系及实体相关

    说了这么久,还没有详细说到abp框架,abp其实基于DDD(领域驱动设计)原则的细看分层如下: 再看我们项目解决方案如下: JCmsErp.Application,应用层:进行展现层与领域层之间的协调 ...