在上一篇文章中说过使用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控制线程的执行顺序的更多相关文章

  1. jmeter 控制线程组执行顺序

    这个要配合全局变量.if和while来实现BeanShell取样器,全局变量:${__setProperty(newswitch,${switch1},)}if条件:"${__P(newsw ...

  2. join控制线程的执行循序 T1 -> T2 -> T3

    /** * 控制线程的执行循序 T1 -> T2 -> T3 * join实现 */ public static void join(){ Thread t1 = new Thread(( ...

  3. Java之CountDownLatch ---控制线程执行顺序

    一,类介绍 这是java.util.concurrent包里的一个同步辅助类,它有两个主要的常用方法  countDown()方法以及await()方法.在完成一组正在其他线程中执行的操作之前,它允许 ...

  4. jmeter的线程组执行顺序不以其出现的顺序发生变化

    jmeter可以同时配置多个线程组,那么他们的执行顺序是什么呢?和他们出现的顺序有什么关系呢? 先说下几个特殊的线程组:tearDown线程组和setUp线程组,tearDown线程组一定在最后执行, ...

  5. Jmeter 同一个测试计划下的多个线程组 执行顺序 希望调整为顺序执行

    用Jmeter做自动化测试,一个测试计划中添加多个线程组, 每个线程组的功能测试,希望是一个线程组执行完毕后,接着执行下一个线程组下的请求 Jmeter默认多个线程组之间是并行关系 需要在测试计划下勾 ...

  6. shell 脚本控制命令的执行顺序

    &&,||,(),{},& 五个符号的运用shell脚本执行命令的时候,有时候会依赖于前一个命令是否执行成功.而&&和||就是用来判断前一个命令执行效果的. 也 ...

  7. Qt 控制线程的顺序执行(使用QWaitCondition,并且线程类的run函数里记得加exec(),使得线程常驻)

    背景项目中用到多线程,对线程的执行顺序有要求: A.一个线程先收数据 B.一个线程处理数据 C.一个线程再将处理后的数据发送出去 要求三个线程按照ABC的顺序循环执行. 思路子类化多线程方法 重写子类 ...

  8. 【Java多线程系列四】控制线程执行顺序

    假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...

  9. Servlet 3.0 之@WebFilter怎么控制多个filter的执行顺序

    之前我们控制多个filter的执行顺序是通过web.xml中控制filter的位置来控制的,放在上面的会比放在下面的先执行,如下“用户登录检查过滤器”会比“接口日志过滤器”先执行   <!-- ...

随机推荐

  1. 《Drools7.0.0.Final规则引擎教程》第3章 3.2 KIE概念&FACT对象

    3.2.1 什么是KIE KIE(Knowledge Is Everything),知识就是一切的简称.JBoss一系列项目的总称,在<Drools使用概述>章节已经介绍了KIE包含的大部 ...

  2. Tiny4412 Android5.0 定制:编译生成img后如何删除原厂的apk

    在android-5.0.2/build/core/Makefile的315行可以看到,这里是apk生成签名相关的地方. 315 name := $(TARGET_PRODUCT) 316 ifeq ...

  3. 高性能高并发服务器架构设计探究——以flamigo服务器代码为例

    这篇文章我们将介绍服务器的开发,并从多个方面探究如何开发一款高性能高并发的服务器程序. 所谓高性能就是服务器能流畅地处理各个客户端的连接并尽量低延迟地应答客户端的请求:所谓高并发,指的是服务器可以同时 ...

  4. Android Animation 动画

    动画类型 Android的animation由四种类型组成  Android动画模式 Animation主要有两种动画模式:一种是tweened animation(渐变动画) XML中 JavaCo ...

  5. Python脚本MAC上双击执行,如何设置?

    1.在文件首行添加如下代码: 如果你想使用默认python版本执行当前的脚本,即python2,则需要添加 #!/usr/bin/env python # -*- coding: utf-8 -*- ...

  6. Dell 12G服务器 手动安装RedHat 6.X

    12代服务器,是DELL目前最新产品,有R720,R520,R620,R420,M420 等产品 以下是光盘直接安装Red Hat 6.X 的方法步骤: 1,选择安装盘对应的启动设备 开机按F11,选 ...

  7. 如何在B2C电子商务网站后台添加CNZZ统计代码(转)

    CNZZ作为网站流量数据统计分析工具的一种,和百度统计工具类似,同样也是用于查看分析网站所有流量数据来源的一种站长工具,当然商家可根据自己的习惯在B2C电子商务网站后台添加相应的数据统计代码来管理您的 ...

  8. 记一次印象有点深刻的坑(bug)

    1.该模块的主要功能介绍 该系统是一个网上课程预约系统. 学生进行口语预约(没上课前可以进行取消)--> 等待上课 --> 上完课老师进行完成的确认操作. 2.问题描述 看下图,现在出现的 ...

  9. IE兼容模式与非兼容模式下jq的写法

    1.  $("#LabelRepeatType").removeAttr("disabled");                $("#LabelF ...

  10. Linux yum操作时出现Error: xz compression not available

    yum升级PHP版本的时候出现这个问题 由于CentOS6的系统安装了epel-release-latest-7.noarch.rpm 导致在使用yum命令时出现Error: xz compressi ...