Java并发程序设计(20)并发锁之倒数锁CountDownLatch

1.1. 倒数锁CountDownLatch

CountDownLatch是另外一种线程同步工具。参与倒数的每个线程在工作完成后都执行countDown()方法,当所有线程都执行完后,会唤醒一个或多个在等待倒数计数为0的线程。

package com.test.concurrence;

import java.util.Date;

import java.util.Random;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class CountDownLatchTest {

public static void main(String[] args) {

final CountDownLatch  countDownLatch = new CountDownLatch(10);

ExecutorService  executorService = Executors.newFixedThreadPool(10);

//建立10个倒数线程。

for(int i=0;i<10;i++){

executorService.submit(new Runnable(){

@Override

public void run() {

try {

Thread.sleep(1000* new Random().nextInt(20));

} catch (InterruptedException  e) {

e.printStackTrace();

}

//每个参与倒数的线程都倒数1次,计数减1.

countDownLatch.countDown();

System.out.println("count:" + countDownLatch.getCount() + " , " + new Date());

}

});

}

//建立3个等待倒数计数为0的线程。

for(int i=0;i<3;i++){

executorService.submit(new Runnable(){

@Override

public void run() {

try {

countDownLatch.await();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("ready:" + countDownLatch.getCount() + " , " + new Date());

}

});

}

executorService.shutdown();

}

}

运行结果如下:

count:9 , Sat Mar 18 23:11:16 CST 2017

count:7 , Sat Mar 18 23:11:18 CST 2017

count:8 , Sat Mar 18 23:11:18 CST 2017

count:6 , Sat Mar 18 23:11:20 CST 2017

count:5 , Sat Mar 18 23:11:25 CST 2017

count:4 , Sat Mar 18 23:11:25 CST 2017

count:3 , Sat Mar 18 23:11:26 CST 2017

count:2 , Sat Mar 18 23:11:27 CST 2017

count:1 , Sat Mar 18 23:11:33 CST 2017

count:0 , Sat Mar 18 23:11:33 CST 2017

ready:0 , Sat Mar 18 23:11:33 CST 2017

ready:0 , Sat Mar 18 23:11:33 CST 2017

ready:0 , Sat Mar 18 23:11:33 CST 2017

时间: 2024-11-08 17:29:09

Java并发程序设计(20)并发锁之倒数锁CountDownLatch的相关文章

Java并发程序设计(12)并发锁之可重入锁ReentrantLock

1.1. 可重入锁ReentrantLock ReentrantLock是java并发库中提供的可重入锁.与synchronized同步块相比,有相似也有不同.相似的地方有: (1)都可以实现多线程之间的同步,避免对共享资源的访问冲突. (2)都是可重入的,即一个已经获取锁的线程可以再次获得同一个锁,synchronized也类似. 不同的地方有: (1)ReentrantLock更灵活,获取锁和释放锁可以在同一个方法中,也可以在不同方法中.synchronized通常用在同一个方法体内. (2

Java并发程序设计(15)并发锁之读写锁(续二)写锁降级

1.1.1. 读写锁应用之三写锁降级 ReentrantReadWriteLock还具有写锁降级的特点,而这跟可重入性有一些关系. (1)持有写锁时可以降级为读锁. (2)持有读锁时不能升级为写锁. ReentrantReadWriteLock和ReentrantLock相似的是都有一个特点,就是可重入.可重入指已经获取到锁的线程可以再次获取锁,保证lock和unlock的次数相同即可. package com.test.concurrence; import java.util.Random;

Java并发程序设计(16)并发锁之条件变量

1.1.1. 条件变量应用之等待通知 条件变量Condition提供了一种基于ReentrantLock的事件等待和通知的机制,并且可以监控任意指定的条件,在条件不满足时等待条件满足,其它线程在条件满足时可以通知等待条件的线程,从而唤醒等待中的线程. 下面的代码实现了两件工作分别由两个线程轮流不断执行的效果. package com.test.concurrence; import java.util.concurrent.locks.Condition; import java.util.co

Java并发程序设计(19)并发锁之循环障碍CyclicBarrier

1.1. 循环障碍CyclicBarrier CyclicBarrier用于多个线程在某个同步点达到同步.在所有线程都到达该同步点之前,已经到达同步点的线程会等待其他线程.简单理解可以说CyclicBarrier跟一个旅游团出去旅游是类似的.在旅游团所有队员都到达出发集合地点之前,提前达到的队员只能在集合地点等待其他队员.当所有队员都达到后就可以出发了.循环障碍可以类似于旅游团在每个集合地点都这么等待一次,然后统一前往下一个景点. package com.test.concurrence; im

Java并发程序设计(13)并发锁之读写锁

1.1.1. 读写锁的应用之一读写分离 读写锁ReentrantReadWriteLock相对于ReentrantLock在特定情况下能提高同步性能,这是因为读写锁有以下特点: (1)读和读可以同时进行. 这一点是ReentrantLock所没有的优点. (2)读和写不能同时进行. (3)写和写不能同时进行. 应用读写锁访问资源的代码如下所示. class MySharedResource { private ReadWriteLock lock = new ReentrantReadWrite

Java并发程序设计(21)并发锁之交换器Exchanger

1.1. 交换器Exchanger Exchanger用于在两个线程之间同步的同时交换数据,并且仅仅可以用于两个线程之间,不支持多个线程之间交换. package com.test.concurrence; import java.util.concurrent.Exchanger; public class ExchangerTest { public static void main(String[] args) { //待交换数据的类型为字符串. final Exchanger<Strin

【实战Java高并发程序设计 4】数组也能无锁:AtomicIntegerArray

除了提供基本数据类型外,JDK还为我们准备了数组等复合结构.当前可用的原子数组有:AtomicIntegerArray.AtomicLongArray和AtomicReferenceArray,分别表示整数数组.long型数组和普通的对象数组. 这里以AtomicIntegerArray为例,展示原子数组的使用方式. AtomicIntegerArray本质上是对int[]类型的封装.使用Unsafe类通过CAS的方式控制int[]在多线程下的安全性.它提供了以下几个核心API: //获得数组第

【实战Java高并发程序设计 3】带有时间戳的对象引用:AtomicStampedReference

[实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference AtomicReference无法解决上述问题的根本是因为对象在修改过程中,丢失了状态信息.对象值本身与状态被画上了等号.因此,我们只要能够记录对象在修改过程中的状态值,就可以很好的解决对象被反复修改导致线程无法正确判断对象状态的问题. AtomicStampedReference正是这么做的.它内部不仅维护了对象值,还维护了一个时间戳(我这里把它

(转)java并发对象锁、类锁、私有锁

转自:http://ifeve.com/java-locks/ 建议参考:http://www.zhihu.com/question/28113814 Java类锁和对象锁实践 感谢[jiehao]同学的投稿,投稿可将文章发送到[email protected] 类锁和对象锁是否会冲突?对象锁和私有锁是否会冲突?通过实例来进行说明. 一.相关约定 为了明确后文的描述,先对本文涉及到的锁的相关定义作如下约定: 1. 类锁:在代码中的方法上加了static和synchronized的锁,或者sync