CountDownLatch主要起倒计时计数器作用,它主要有两个方法await()和countDown()。一旦某个线程调用await()方法,那么该线程就会阻塞,等待CountDownLatch计数器倒计时归零,需要注意的是尽管线程调用await()方法后会阻塞,但是CountDownLatch允许别的线程调用countDown()方法,将计数器减一。也就是说调用计时器的线程阻塞后,可以利用别的线程控制调用线程何时从新开始运行。
package demo;
import java.util.concurrent.CountDownLatch;
/**
* 该demo主要想要做的事就是:在主线程中创建N个支线程,让支线程等待主线程将开关计数器startSignal打开。
* 而当主线程打开startSignal开关后,主线程要等待计数器doneSignal归零,
* 而doneSignal计数器归零依赖于每个支线程为主线程的计数器减一。
* 所以当主线程打开开关后,支线程才能运行完毕,而只有支线程全部运行完毕,才能打开主线程的计数器。 这样整个程序才能走完
*
* @author Administrator
*
*/
public class LatchDriverDemo {
public static final int N = 5;
public static void main(String[] args) throws InterruptedException {
// 用于向工作线程发送启动信号
CountDownLatch startSignal = new CountDownLatch(1);
// 用于等待工作线程的结束信号
CountDownLatch doneSignal = new CountDownLatch(N);
// 创建启动线程
System.out
.println("开始创建并运行分支线程,且分支线程启动startSignal计数器,等待主线程将startSignal计数器打开");
for (int i = 0; i < N; i++) {
new Thread(new LatchWorker(startSignal, doneSignal), "t" + i)
.start();
}
// 得到线程开始工作的时间
long start = System.nanoTime();
// 主线程,递减开始计数器,让所有线程开始工作
System.out.println("主线程" + Thread.currentThread().getName()
+ "将startSignal计数器打开");
startSignal.countDown();
// 主线程阻塞,等待所有线程完成
System.out.println("主线程" + Thread.currentThread().getName()
+ "开始倒计时5个数");
doneSignal.await();
/*
* 为什么说运行到下一句,所有线程就全部运行完毕了呢。 因为主线程要倒计时5个数, 而产生的5个支线程在运行完毕前会将主线程的计数器减一,
* 所以如果所有支线程运行完毕了 ,主线程才能继续运行主线程的最后一个打印程序
*/
System.out.println("所有线程运行完毕");
}
}
class LatchWorker implements Runnable {
// 用于等待启动信号
private final CountDownLatch startSignal;
// 用于发送结束信号
private final CountDownLatch doneSignal;
LatchWorker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
// 一旦调用await()方法,该线程就会开始阻塞。知道计数器startSignal为0
System.out.println(Thread.currentThread().getName()
+ " 开始调用await()方法,等待计数器startSignal被主线程打开");
startSignal.await();
doWork();
System.out
.println(Thread.currentThread().getName() + " 将主线程的计数器减一");
doneSignal.countDown();// 发送完成信号
} catch (InterruptedException ex) {
}
}
void doWork() {
System.out.println(Thread.currentThread().getName()
+ " 的计数器被打开,分支线程开始运行");
int sum = 0;
for (int i = 0; i < 10000; i++) {
sum += i;
}
}
}
程序运行结果:
开始创建并运行分支线程,且分支线程启动startSignal计数器,等待主线程将startSignal计数器打开
t0 开始调用await()方法,等待计数器startSignal被主线程打开
t1 开始调用await()方法,等待计数器startSignal被主线程打开
t2 开始调用await()方法,等待计数器startSignal被主线程打开
主线程main将startSignal计数器打开
t4 开始调用await()方法,等待计数器startSignal被主线程打开
t3 开始调用await()方法,等待计数器startSignal被主线程打开
t3 的计数器被打开,分支线程开始运行
t0 的计数器被打开,分支线程开始运行
t2 的计数器被打开,分支线程开始运行
t3 将主线程的计数器减一
t0 将主线程的计数器减一
t2 将主线程的计数器减一
t4 的计数器被打开,分支线程开始运行
t1 的计数器被打开,分支线程开始运行
主线程main开始倒计时5个数
t4 将主线程的计数器减一
t1 将主线程的计数器减一
所有线程运行完毕
分享到:
相关推荐
主要介绍了Java多线程编程之CountDownLatch同步工具使用实例,需要的朋友可以参考下
mybaits 多线程 实现数据批量插入 (运用CountDownLatch实现闭锁) 1、mybatis批处理 2、数据分批量查询 3、数据分批量插入
在Java中和ReadWriteLock.ReadLock一样,CountDownLatch的本质也是一个"共享锁",这里我们就来详解Java多线程编程中CountDownLatch阻塞线程的方法:
利用 CountDownLatch 类实现线程同步,而不用回调机制。详见我的博文 http://blog.csdn.net/kroclin/article/details/37956949
主要参考资料:java并发编程的艺术、Java并发——同步工具类 二、CountDownLatch(同步倒数计数器)–不仅仅用于多线程 1.作用:允许一个或多个线程等待其他线程完成操作。 CountDownLatch的构造函数...
本篇文章主要介绍了Java中多线程同步类 CountDownLatch的相关知识,具有很好的参考价值。下面跟着小编一起来看下吧
同步控制是并发程序必不可少的重要手段,本文我们将通过重入锁、读写锁、信号量、倒计数器和循环栅栏以及他们的实例来介绍Java并发程序中的同步控制。 目录线程安全 Thread Safety重入锁 ReentrantLock读写锁 ...
主要介绍了如何使用CountDownLatch同步java多线程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
NULL 博文链接:https://cpjsjxy.iteye.com/blog/2272451
主要介绍了Java多线程同步器代码详解,文章分别介绍了是CountDownLatch,Semaphore,Barrier和Exchanger以及其相关代码示例,具有一定参考价值,需要的朋友可以了解下。
主要为大家详细介绍了使用CountDownLatch等待多线程全部执行完成,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
实现多线程任务的同步 3.1 场景介绍 3.2 使用CountDownLatch实现同步 主线程等待多个线程完成 4.1 场景介绍 4.2 使用CountDownLatch实现等待 CountDownLatch的其他应用场景 5.1 倒计时计时器 5.2 同时开始任务 5.3 ...
java并发编程中CountDownLatch和CyclicBarrier的使用借鉴.pdf
看完《think in java》多线程章节,自己写的多线程文档,还结合了其他的相关网络资料。 线程 一. 线程池 1)为什么要使用线程池 2 2)一个具有线程池的工作队列 3 3)使用线程池的风险: 4 4)有效使用线程池的原则 5...
主要介绍了JAVA多线程CountDownLatch的使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
主要介绍了Java线程并发工具类CountDownLatch原理及用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
java并发编程中CountDownLatch和CyclicBarrier的使用.pdf
主要介绍了Java中CountDownLatch进行多线程同步详解及实例代码的相关资料,需要的朋友可以参考下
内容概要:最新2023年Java高并发多线程后端面试题整理, 包含线程池,并发集合,volatile,CountDownLatch,Semaphore,Phaser,AQS,ReentrantLock,ReentrantLock等等问题, 用简洁明了的语言,通俗易懂地阐述了高...
Java多线程入阶干货分享 1.使用线程的经验:设置名称、响应中断、使用ThreadLocal 2.Executor:ExecutorService和Future 3.阻塞队列:put和take、offer和poll、drainTo 4.线程间通信:lock、condition、wait、notify...