关于CountDownLatch控制线程的执行顺序
在上一篇文章中说过使用thread.join()方法、newSingleThreadExecutor单线程池来控制线程执行顺序。在文章的末尾我提出了一种构想,可否使用经典的生产者和消费者模型来控制执行顺序。在本文中,我将使用CountDownLatch来解决这个问题。
上图是countDownLatch的原理示意图。官方文档给出的解释是:CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程执行完后再执行。上图中线程A调用方法await()之后,进行阻塞,然后线程1执行任务完毕,数量减1,到最后线程2、3执行完毕,count=0。那么此时线程A等待了所有的线程执行完毕了任务。线程A状态复位,开始继续执行任务。
实现过程如下:
public class ThreadOrderTest { public static void main(String[] args) {
/**
* 创建线程类的时候,将上一个计数器和本线程计数器传入。运行前业务执行上一个计数器.await, 执行后本计数器.countDown。
*/ CountDownLatch num0 = new CountDownLatch(0);// 在这里count为0,表示该线程立马复位执行
CountDownLatch num1 = new CountDownLatch(1);// 在这里count为0,表示该线程立马复位执行
CountDownLatch num2 = new CountDownLatch(1);// 在这里count为0,表示该线程立马复位执行
Thread t1 = new Thread(new Count(num0, num1));
Thread t2 = new Thread(new Count(num1, num2));
Thread t3 = new Thread(new Count(num2, num2)); t1.start();
t2.start();
t3.start(); } static class Count implements Runnable { CountDownLatch num1;
CountDownLatch num2; /**
* 该构造器传递了上一个线程的计数器和当前线程的计数器
*
* @param num0
* @param num1
*/
public Count(CountDownLatch num1, CountDownLatch num2) {
super();
this.num1 = num1;
this.num2 = num2;
} @Override
public void run() {
try {
// 等待线程1执行完毕线程2开始执行,因为线程1开始立马就会执行(count=0)
num1.await();
System.out.println("开始执行线程:" + Thread.currentThread().getName());
num2.countDown();// 本线程计数器减少
} catch (InterruptedException e) {
e.printStackTrace();
} } } }
具体是怎么实现的呢:首先在创建线程的时候传递了Runnable对象,而该对象设置了两个参数,第一个参数保存了前一个线程的计数器,第二个线程保存了当前线程的计数器。线程1初始化的时候设置了线程的计数器为0,也就是说会立马执行任务,执行完毕,线程2 的计数器调用countdown()方法,立马从初始化的1变为0,同样开始执行,那么此时执行完毕,线程3计数器也减去1,开始执行任务。这样保证了三个线程的执行顺序。
下面是执行的结果:
开始执行线程:Thread-0
开始执行线程:Thread-1
开始执行线程:Thread-2
要说明的是,CountDownLatch存在不足的地方在于,要创建该对象的时候,我们会传递计数器的初始值,但是这个值一经设置,就再也无法修改了,因此计数器的使用时一次性的。这就是java.util.CountDownLatch的不足之处了吧!

关于CountDownLatch控制线程的执行顺序的更多相关文章
- jmeter 控制线程组执行顺序
这个要配合全局变量.if和while来实现BeanShell取样器,全局变量:${__setProperty(newswitch,${switch1},)}if条件:"${__P(newsw ...
- join控制线程的执行循序 T1 -> T2 -> T3
/** * 控制线程的执行循序 T1 -> T2 -> T3 * join实现 */ public static void join(){ Thread t1 = new Thread(( ...
- Java之CountDownLatch ---控制线程执行顺序
一,类介绍 这是java.util.concurrent包里的一个同步辅助类,它有两个主要的常用方法 countDown()方法以及await()方法.在完成一组正在其他线程中执行的操作之前,它允许 ...
- jmeter的线程组执行顺序不以其出现的顺序发生变化
jmeter可以同时配置多个线程组,那么他们的执行顺序是什么呢?和他们出现的顺序有什么关系呢? 先说下几个特殊的线程组:tearDown线程组和setUp线程组,tearDown线程组一定在最后执行, ...
- Jmeter 同一个测试计划下的多个线程组 执行顺序 希望调整为顺序执行
用Jmeter做自动化测试,一个测试计划中添加多个线程组, 每个线程组的功能测试,希望是一个线程组执行完毕后,接着执行下一个线程组下的请求 Jmeter默认多个线程组之间是并行关系 需要在测试计划下勾 ...
- shell 脚本控制命令的执行顺序
&&,||,(),{},& 五个符号的运用shell脚本执行命令的时候,有时候会依赖于前一个命令是否执行成功.而&&和||就是用来判断前一个命令执行效果的. 也 ...
- Qt 控制线程的顺序执行(使用QWaitCondition,并且线程类的run函数里记得加exec(),使得线程常驻)
背景项目中用到多线程,对线程的执行顺序有要求: A.一个线程先收数据 B.一个线程处理数据 C.一个线程再将处理后的数据发送出去 要求三个线程按照ABC的顺序循环执行. 思路子类化多线程方法 重写子类 ...
- 【Java多线程系列四】控制线程执行顺序
假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...
- Servlet 3.0 之@WebFilter怎么控制多个filter的执行顺序
之前我们控制多个filter的执行顺序是通过web.xml中控制filter的位置来控制的,放在上面的会比放在下面的先执行,如下“用户登录检查过滤器”会比“接口日志过滤器”先执行 <!-- ...
随机推荐
- Could not find a valid gem 'rails' (>= 0), here is why
很长一段时间之前 Ruby Rails入门--windows下搭建Ruby Rails Web开发环境 ,由于后来将Ruby的安装文件从 C 盘移动到了 D 盘,也修改了 Path 环境变量,ruby ...
- ng $interval(周期性定时器) $timeout(延迟定时器)
<!DOCTYPE html> <html ng-app="myApp"> <head lang="en"> <met ...
- 旧书重温:0day2【5】shellcode变形记
紧接上一篇,结合第一篇 //这篇文章主要成功溢出一个带有缓冲区溢出的小程序,其中我们的shellcode被strcpy截断了所以我们需要变形shellcode,这个实验中也出现了很多意想不到的拦路虎, ...
- 【MFC】MFC DLEdit 设计属于自己的编辑框_鼠标悬停
MFC DLEdit 设计属于自己的编辑框 2012-02-04 13:00 by 捣乱小子, 3543 阅读, 5 评论, 收藏, 编辑 起因 无意间看到了大牛们写的自定义编辑框控件,于是找了个时间 ...
- Linux部分常用命令学习(二)
1.wc:wc命令是一个统计的工具,主要用来显示文件所包含的行.字和字节数.wc命令是word count的缩写. 命令格式:wc [选项参数] [文件] 选项参数: -c 统计字节数 -l 统计行数 ...
- Protobuf-net 应用
什么是ProtoBuf-net Protobuf是google开源的一个项目,是基于二进制的类似于XML,JSON这样的数据表示语言,用户数据序列化反序列化,google声称google的数据通信都是 ...
- java的日期加减
在mysql里面
- Mysql 拿指定经纬度与数据库多条经纬度进行距离计算 (转)
公式如下,单位米: 第一点经纬度:lng1 lat1 第二点经纬度:lng2 lat2 round(6378.138*2*asin(sqrt(pow(sin( (lat1*pi()/180-lat2* ...
- window下安装mysql
参考地址: https://www.cnblogs.com/lmh2072005/p/5656392.html http://www.jb51.net/article/90302.htm 一.下载安装 ...
- 【转】java接口的性能测试
这周尝试了一把性能测试,之前都是测试网站的性能测试,java接口的性能测试还是头一次,学到了很多,特此分享一下. 主要用到了两个性能测试工具,一个是jmeter,一个是LoadRunner. 使用jm ...