一、闭锁(Latch)

   闭锁(Latch):一种同步方法,可以延迟线程的进度直到线程到达某个终点状态。通俗的讲就是,一个闭锁相当于一扇大门,在大门打开之前所有线程都被阻断,一旦大门打开所有线程都将通过,但是一旦大门打开,所有线程都通过了,那么这个闭锁的状态就失效了,门的状态也就不能变了,只能是打开状态。也就是说闭锁的状态是一次性的,它确保在闭锁打开之前所有特定的活动都需要在闭锁打开之后才能完成。

应用场景:

1、确保某个计算在其需要的所有资源都被初始化之后才继续执行。二元闭锁(包括两个状态)可以用来表示“资源R已经被初始化”,而所有需要R的操作都必须先在这个闭锁上等待;

2、确保某个服务在其依赖的所有其他服务都已经启动之后才启动;

3、等待直到某个操作的所有参与者都就绪在继续执行。(例如:多人游戏中需要所有玩家准备才能开始);

二、CountDownLatch

CountDownLatch是一个同步辅助类,用于允许一个或多个线程等待直到多个线程完成一组操作。CountDownLatch初始化时指定一个计数器count,当某个线程完成操作时可以调用countDown()将计数器count减一,任何线程调用CountDownLatch的await()方法都会阻塞直到count等于0。

如上图:主线程TA初始化了一个count=3的CountDownLatch,同时启动三个线程T1,T2,T3  处理一些业务逻辑,TA调用await()方法进入阻塞直到三个线程完成操作。当T1,T2,T3完成操作时,各自调用countDown()将计数器减一,当count=0时TA才会恢复运行。

注意:CountDownLatch 的计数器Count不能重置。

CountDownLatch是一个灵活的闭锁实现,用于如下情况:允许一个或多个线程等待一个事件集的发生。闭锁的状态包括一个计数器,初始化为一个正数,用来实现需要等待的事件数。CountDown方法对计数器做减操作,表示一个事件已经发生了,而await方法等待计数器达到零,此时所有需要等待的事件已发生。如果计数器入口时值为非零,await会一直阻塞直到计数器为零,或者等待线程中断以及超时.

在完成一组正在其他线程中执行的操作之前,它允许线程一直等待。在一些应用场合中,需要等待某个条件达到要求后才能做后面的事情;这个时候就可以使用CountDownLatch。CountDownLatch最重要的方法是countDown()和await(),前者将计数器减一,后者是等待计数到0,如果没有到达0,就阻塞等待。
CountDownLatch强调的是一个线程(或多个)需要等待另外的n个线程干完某件事情之后才能继续执行。CountDownLatch 的初始阀值一旦设置就只能递减下去,无法重置

调用CountDownLatch对象的await()方法则处于等待状态,调用countDown()方法就将计数器减1,当计数到达0时,则所有等待者或单个等待者开始执行。

 三、应用举例

1、模拟最大并发数的例子

2、有三个工人在为老板干活,这个老板有一个习惯,就是当三个工人把一天的活都干完了的时候,他就来检查所有工人所干的活。记住这个条件:三个工人先全部干完活,老板才检查。所以在这里用Java代码设计两个类,Worker代表工人,Boss代表老板

工人:

package LatchAndCyclicBarrier;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class Work implements Runnable{
        private CountDownLatch downLatch;
        private String name;
        public Work(CountDownLatch downLatch, String name){
            this.downLatch = downLatch;
            this.name = name;
        }


        public void run() {
            this.doWork();
            try{
                TimeUnit.SECONDS.sleep(new Random().nextInt(10));
            }catch(InterruptedException ie){
            }
            System.out.println(this.name + "活干完了!");
            this.downLatch.countDown();

}

private void doWork(){
            System.out.println(this.name + "正在干活!");
        }

}
老板:

package LatchAndCyclicBarrier;
import java.util.concurrent.CountDownLatch;
public class Boss implements Runnable{
        private CountDownLatch downLatch;
        public Boss(CountDownLatch downLatch){
            this.downLatch = downLatch;
        }
        public void run() {
            System.out.println("老板正在等所有的工人干完活......");
            try {
                this.downLatch.await();
            } catch (InterruptedException e) {
            }
            System.out.println("工人活都干完了,老板开始检查了!");
        }
    }
测试代码:

package LatchAndCyclicBarrier;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestLatch {
    public static void main(String[] args) {
            ExecutorService executor = Executors.newCachedThreadPool();
            CountDownLatch latch = new CountDownLatch(3);
            Work w1 = new Work(latch,"张三");
            Work w2 = new Work(latch,"李四");
            Work w3 = new Work(latch,"王二");

Boss boss = new Boss(latch);

executor.execute(w3);
            executor.execute(w2);
            executor.execute(w1);
            executor.execute(boss);
            executor.shutdown();
        }
    }
执行结果:

李四正在干活!
老板正在等所有的工人干完活......
王二正在干活!
张三正在干活!
李四活干完了!
王二活干完了!
张三活干完了!
工人活都干完了,老板开始检查了!

CountDownLatch和CyclicBarrier的主要联系和区别如下:
1.闭锁CountDownLatch做减计数,而栅栏CyclicBarrier则是加计数。
2.CountDownLatch是一次性的,CyclicBarrier可以重用。
3.CountDownLatch强调一个线程等多个线程完成某件事情。CyclicBarrier是多个线程互等,等大家都完成。
4.鉴于上面的描述,CyclicBarrier在一些场景中可以替代CountDownLatch实现类似的功能。

更贴切的例子请参见:http://www.cnblogs.com/liuling/p/2013-8-20-02.html

http://suhuanzheng7784877.iteye.com/blog/1145289

CountDownLatch(闭锁)的更多相关文章

  1. 6. CountDownLatch 闭锁

    package com.gf.demo05; import java.util.concurrent.CountDownLatch; /** * CountDownLatch : 闭锁,在完成某些操作 ...

  2. juc并发工具类之CountDownLatch闭锁

    import java.util.concurrent.CountDownLatch; /** * 闭锁: 在进行某些运算时, 只有其他所有线程的运算全部完成,当前运算才继续执行(程序流中加了一道栅栏 ...

  3. 同步机制之--java之CountDownLatch闭锁

    CountDownLatch闭锁 1.类介绍 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待.用给定的计数初始化 CountDownLatch.CountDown ...

  4. CountDownLatch闭锁

    CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 闭锁可以延迟线程的进度直到其到达终止状态,闭锁可以用来确保某些活动直到其他活动都完 ...

  5. 【同步工具类】CountDownLatch闭锁任务同步

    [同步工具类]CountDownLatch闭锁任务同步 转载:https://www.cnblogs.com/yangchongxing/p/9214284.html 打过dota的同学都知道,多人一 ...

  6. CopyOnWriteArrayList(写入并复制) & CountDownLatch(闭锁)

    ConcurrentHashMap: ①Java 5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器 的性能.② ConcurrentHashMap 同步容器 ...

  7. CountDownLatch——闭锁的实现之一

    CountDownLatch实际上是一种闭锁实现.闭锁:是一种同步工具类,可以延迟线程的进度知道其到达终止状态--<Java并发编程实战>.这个怎么解释呢?简单来说,就是有1个线程需要等待 ...

  8. CountDownLatch 闭锁、FutureTask、Semaphore信号量、Barrier栅栏

    同步工具类可以是任何一个对象.阻塞队列可以作为同步工具类,其他类型的同步工具类还包括信号量(Semaphore).栅栏(Barrier).以及闭锁(Latch). 所有的同步工具类都包含一些特定的结构 ...

  9. Java并发编程笔记之 CountDownLatch闭锁的源码分析

    JUC 中倒数计数器 CountDownLatch 的使用与原理分析,当需要等待多个线程执行完毕后在做一件事情时候 CountDownLatch 是比调用线程的 join 方法更好的选择,CountD ...

随机推荐

  1. 问题:关于坛友的一个定时重复显示和隐藏div的实现

    需求:打开页面只看到DIV2,等完秒数之后在显示DIV3.手动关闭DIV3后在重新数秒 我设置的间隔时间是3秒,代码如下: html+css: 1: <!DOCTYPE HTML> htm ...

  2. HDU 1024 DP Max Sum Plus Plus

    题意:本题的大致意思为给定一个数组,求其分成m个不相交子段和最大值的问题. kuangbin专题. dp[i][j]=Max(dp[i][j-1]+a[j] , max( dp[i-1][k] ) + ...

  3. HW6.6

    public class Solution { public static void main(String[] args) { int[] prime = new int[50]; prime[0] ...

  4. Thinking in Java

    今天无意中看到了这本书(Thinking in Java)的中关于多态的一段描述,瞬间就感觉到了多态原来是这样的.

  5. 编译vo-aacenc遇到的问题

    sourceforge更新了vo-aacenc到0.1.3,就把自己的编码器也更新到最新.编译过程中无聊多测试了一下 发现一个小问题http://sourceforge.net/projects/op ...

  6. 使用Intent在活动之间穿梭(《第一行代码》读书笔记)

    以下全是个人理解//瞎扯 其实活动理解理解起来就像一个个函数 那么Intent就是调用函数和参数传递 可以有无参,仅仅是调用 Intent intent = new Intent(A.this, B. ...

  7. 转载ASP.NET MVC 中@Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction区别

    对这四个的区别做一个总结,清理一下思路,方便以后使用: 1.带有Render的方法返回值是void,在方法内部进行输出:不带的返回值类型为MvcHtmlString,所以只能这样使用:     @Ht ...

  8. 【Stage3D学习笔记续】山寨Starling(三):Starling核心渲染流程

    这篇文章我们剔除Starling的Touch事件体系和动画体系,专门来看看Starling中的渲染流程实现,以及其搭建的显示列表结构. 由于Starling是模仿Flash的原生显示列表,所以我们可以 ...

  9. 本地或者是koala软件编译less文件为css

    背景: 事情的起因是这般的,平时工作是在线上办公,样式是使用less来写,于是乎,这样我从线上download下来的less文件无法直接在自己的本地环境运行.有一个问题就是我要把less文件先编译成c ...

  10. PHP中各种Hash算法性能比较

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...