使用 CountDownLatch 控制多个线程执行顺序
已同步更新至:http://dxjia.cn/2015/08/countdownlatch-use/
有时候会有这样的需求,多个线程同时工作,然后其中几个可以随意并发执行,但有一个线程需要等其他线程工作结束后,才能开始。举个例子,开启多个线程分块下载一个大文件,每个线程只下载固定的一截,最后由另外一个线程来拼接所有的分段,那么这时候我们可以考虑使用CountDownLatch来控制并发。
CountDownLatch是JAVA提供在java.util.concurrent包下的一个辅助类,可以把它看成是一个计数器,其内部维护着一个count计数,只不过对这个计数器的操作都是原子操作,同时只能有一个线程去操作这个计数器,CountDownLatch通过构造函数传入一个初始计数值,调用者可以通过调用CounDownLatch对象的cutDown()方法,来使计数减1;如果调用对象上的await()方法,那么调用者就会一直阻塞在这里,直到别人通过cutDown方法,将计数减到0,才可以继续执行。
示例
import java.util.concurrent.CountDownLatch;
public class Sample {
/**
* 计数器,用来控制线程
* 传入参数2,表示计数器计数为2
*/
private final static CountDownLatch mCountDownLatch = new CountDownLatch(2);
/**
* 示例工作线程类
*/
private static class WorkingThread extends Thread {
private final String mThreadName;
private final int mSleepTime;
public WorkingThread(String name, int sleepTime) {
mThreadName = name;
mSleepTime = sleepTime;
}
@Override
public void run() {
System.out.println("[" + mThreadName + "] started!");
try {
Thread.sleep(mSleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
mCountDownLatch.countDown();
System.out.println("[" + mThreadName + "] end!");
}
}
/**
* 示例线程类
*/
private static class SampleThread extends Thread {
@Override
public void run() {
System.out.println("[SampleThread] started!");
try {
// 会阻塞在这里等待 mCountDownLatch 里的count变为0;
// 也就是等待另外的WorkingThread调用countDown()
mCountDownLatch.await();
} catch (InterruptedException e) {
}
System.out.println("[SampleThread] end!");
}
}
public static void main(String[] args) throws Exception {
// 最先run SampleThread
new SampleThread().start();
// 运行两个工作线程
// 工作线程1运行5秒
new WorkingThread("WorkingThread1", 5000).start();
// 工作线程2运行2秒
new WorkingThread("WorkingThread2", 2000).start();
}
}
运行结果:
[SampleThread] started!
[WorkingThread1] started!
[WorkingThread2] started!
[WorkingThread2] end!
[WorkingThread1] end!
[SampleThread] end!
达到了目的。当然还有其他方式可以做到这样的效果,本文仅仅是介绍了一种使用CountDownLatch的方式。
使用 CountDownLatch 控制多个线程执行顺序的更多相关文章
- CountDownLatch同步工具--控制多个线程执行顺序
好像倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当到达0时,所有等待者就开始执行. java.util.concurrent.CountDownLatch ...
- Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行
Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行 Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执 ...
- 【Java多线程系列四】控制线程执行顺序
假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...
- Java多线程系列四——控制线程执行顺序
假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...
- python+unittest 控制用例的执行顺序
unittest的main()方法执行用例的顺序是按照测试类.测试方法的名字的ASCII顺序来执行测试方法.所以可能执行的顺序和你想要的顺序不一样,可能通过下面两种方法修改执行顺序 1. 通过Test ...
- python unittest控制用例的执行顺序
为什么要进行顺序控制呢?使用过testng的同学就知道,它相对于junit来说有更强大的功能,其中的一个功能就是依赖测试.什么是依赖测试呢?简单的说一下就是,A方法运行时,其中有个变量的取值是B方法的 ...
- Java之CountDownLatch ---控制线程执行顺序
一,类介绍 这是java.util.concurrent包里的一个同步辅助类,它有两个主要的常用方法 countDown()方法以及await()方法.在完成一组正在其他线程中执行的操作之前,它允许 ...
- gcd 控制线程执行顺序(供参考)
dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_qu ...
- 关于for 循环里 线程执行顺序问题
最近在做项目时遇到了 这样的需求 要在一个for循环里执行下载的操作, 而且要等 下载完每个 再去接着走循环.上网查了一些 觉得说的不是很明确.现在把我用到的代码 贴上 希望可以帮到有此需求的开发者 ...
随机推荐
- Java中FileOutputStream和FileInputStream使用例子
package a.ab; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.F ...
- React与ES6(四)ES6如何处理React mixins
React与ES6系列: React与ES6(一)开篇介绍 React和ES6(二)ES6的类和ES7的property initializer React与ES6(三)ES6类和方法绑定 React ...
- 对IEnumerable<T>和IQueryable<T>的一点见解
今天学习了用EF模型做查询,感觉数据库上下文对象的扩展方法很强大,所以研究了一下where的实现原理,其中遇到了一个问题,就是关于IEnumerable和IQueryable的区别,所以查了查资料,这 ...
- c# 后台调前台的js
ScriptManager.RegisterStartupScript(this.Page, typeof(Page), "", "<script type=\&q ...
- day7----面向对象编程进阶
本节内容: 面向对象高级语法部分 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 静态方法 它与类唯一的关联就是需要通过类名来调用这个方法 #静态方法实际跟类没关系,不 ...
- PHP部分字符串函数汇总
PHP部分字符串函数汇总 提交 我的评论 加载中 已评论 PHP部分字符串函数汇总 2015-03-10 PHP100中文网 PHP100中文网 PHP100中文网 微信号 功能介绍 互联网开发者社区 ...
- 第七天:JS内置对象-String字符串对象
1.String对象 String对象用于处理已有的字符串 字符串可以使用双引号或单引号 String对象有一些常用的方法和属性,例如length 示例代码: <!DOCTYPE html&g ...
- eclipse 打开是报错"reload maven project has encountered a problem"
不需要删除整个 .metadata 如果删除这个代价是重新导入全部项目 D:\eclipse-workspace\.metadata\.plugins\org.eclipse.e4.workbench ...
- chrome浏览器扩展的事件处理
关于chrome扩展开发的栗子已经有很多了,问问度娘基本能满足你的欲望, 我想说的是扩展和页面间的数据传递问题. 我们知道写扩展有个必须的文件就是“manifest.json”, 这个里面定义了一个和 ...
- bzoj 3399: [Usaco2009 Mar]Sand Castle城堡
3399: [Usaco2009 Mar]Sand Castle城堡 Time Limit: 3 Sec Memory Limit: 128 MB Description 约翰用沙子建了一座城堡.正 ...