如果现在有五个线程A、B、C、D、E,请问如何用E线程用于统计A、B、C、D四个线程的结果?

题意需要用E线程统计A、B、C、D四个线程,也就是说E线程必须要等到前面四个线程运行结束之后才能执行。那么如何使用E线程来统计前面四个线程的结果呢?

下面介绍两种实现方法:

一、CountDownLatch

CountDownLatch是一种java.util.concurrent包下一个同步工具类,它允许一个或多个线程等待直到在其他线程中一组操作执行完成。

我们可以将CountDownLatch看作一个计数器,可以给定其一个数来对其进行初始化。当它计数的值变为0时,才可以执行后续的步骤。

public CountDownLatch(int count)

CountDownLatch有两个方法是我们常用的:await();和countDown();

await()函数用于阻塞当前线程直到CountDownLatch的计数值变为0;

countDown()方法用于将当前CountDownLatch的计数值减1;

简单的介绍了CountDownLatch的作用和用法之后,我们看下如下的代码:

import java.util.concurrent.CountDownLatch;
public class Test1{
public static void main(String[] args) throws InterruptedException {
int number = 3;
CountDownLatch latch = new CountDownLatch(number); for(int i=0;i<3;i++){
ThreadDemo demo = new ThreadDemo(latch);
demo.start();
System.out.println(i);
}
latch.await();
System.out.println("Check it Out");
}
} class ThreadDemo extends Thread{ private CountDownLatch latch; public ThreadDemo(CountDownLatch latch){
this.latch = latch;
} public void run(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
}

我们首先创建了一个CountDownLatch对象给定一个number将其初始化,需要注意的是当前CountDownLatch对象的值减为0之后,该对象便失去了作用。

同时我们提供了继承自Thread的ThreadDemo类,它包含了一个CountDownLatch对象。当我们创建ThreadDemo对象时,会将CountDowmLatch对象注入其中。

在TreadDemo类的run()方法中,我们执行了两步动作:延迟5秒后将CountDownLatch的计数值减1。

在main函数中,我们利用for循环创建了三个ThreadDemo对象并执行他们的run()方法。添加和不添加latch.await()语句将会得到两种执行结果。

1、添加latch.await()语句

  执行结果:

  0

  1

  2

  Check it Out

  我们会发现0 1 2几乎是同时打印出来的,但是“Check it Out”大概等待了5秒左右的时间后才打印,这说明了其实“Check it Out”是等待前面三个线程执行完countDown()方法之后将latch的值减为0之后才执行的。

2、无latch.await()语句

  执行结果:

  0

  1

  2

  Check it Out

  观察运行结果我们会发现,0 1 2和“Check it Out”几乎是同时出现的,也就是说“Check it Out”并没有等待前面三个线程执行完成之后才执行。

  CountDowLlatch的用途即是让一组线程先执行,知道countdownlatch对象的计数值到0后,让后续的线程继续执行。

二、join方法实现

  事实上,join方法也可以实现同样的效果!代码如下:

import java.util.concurrent.CountDownLatch;
public class Test{
public static void main(String[] args) throws InterruptedException {
int number = 3;
CountDownLatch latch = new CountDownLatch(number);
ThreadDemo thread1 = new ThreadDemo(1);
ThreadDemo thread2 = new ThreadDemo(2);
thread1.start();
thread1.join();
System.out.println("----");
thread2.start();
thread2.join();
System.out.println("main is end!"); }
} class ThreadDemo extends Thread{
private int number;
public ThreadDemo(int number){
this.number = number;
}
public void run(){
System.out.println("Thread"+number+" is running");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread"+number+"is end");
}
}

运行结果如下:


Thread1 is running

Thread1is end

----

Thread2 is running

Thread2is end

main is end!

可以看到thread1阻塞了thread2,只有当thread1和thread2均执行结束后,main方法才能继续执行。如果想要thread1和thread2同时执行的话,只需要做如下简单的变动。

thread1.start();
thread1.join();
thread2.start();
thread2.join(); System.out.println("main is end!");

运行结果如下:

Thread1 is running

Thread2 is running

Thread1is end

Thread2is end

main is end!

因此,如果我们需要某些线程等待指定任务执行完毕之后执行,选择join方法也是一种选择;

多线程CountDownLatch和Join的更多相关文章

  1. 关于python多线程编程中join()和setDaemon()的一点儿探究

    关于python多线程编程中join()和setDaemon()的用法,这两天我看网上的资料看得头晕脑涨也没看懂,干脆就做一个实验来看看吧. 首先是编写实验的基础代码,创建一个名为MyThread的  ...

  2. JAVA多线程之CountDownLatch与join的区别

    首先,我们来看一个应用场景1: 假设一条流水线上有三个工作者:worker0,worker1,worker2.有一个任务的完成需要他们三者协作完成,worker2可以开始这个任务的前提是worker0 ...

  3. CountDownLatch与join的区别和联系

    首先,我们来看一个应用场景1: 假设一条流水线上有三个工作者:worker0,worker1,worker2.有一个任务的完成需要他们三者协作完成,worker2可以开始这个任务的前提是worker0 ...

  4. 转:java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例

    java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例 1.CountDownLatch:一个同步工具类,它允许一个或多个线程一 ...

  5. 多线程进阶---Thread.join()/CountDownLatch.await() /CyclicBarrier.await()

    Thread.join() CountDownLatch.await() CyclicBarrier.await() 三者都是用来控制程序的"流动" 可以让程序"堵塞&q ...

  6. 跟着ZooKeeper学Java——CountDownLatch和Join的使用

    在阅读ZooKeeper的源码时,看到这么一个片段,在单机模式启动的时候,会调用下面的方法,根据zoo.cfg的配置启动单机版本的服务器: public void runFromConfig(Serv ...

  7. Java多线程--wait和join

    首先从公司一道笔试题开始 package test; public class Test implements Runnable { public int i = 0; @Override publi ...

  8. Java多线程-CountDownLatch、CyclicBarrier、Semaphore

    上次简单了解了多线程中锁的类型,今天要简单了解下多线程并发控制的一些工具类了. 1. 概念说明: CountDownLatch:相当于一个待执行线程计数器,当计数减为零时表示所有待执行线程都已执行完毕 ...

  9. 并发编程大师系列之:CountDownLatch和Join

    业务场景描述:假设一条流水线上有三个工作者:worker1,worker2,worker3.有一个任务的完成需要他们三者协作完成,worker3可以开始这个任务的前提是worker1和worker2完 ...

随机推荐

  1. ACM 海贼王之伟大航路(深搜剪枝)

    "我是要成为海贼王的男人!" 路飞他们伟大航路行程的起点是罗格镇,终点是拉夫德鲁(那里藏匿着"唯一的大秘宝"--ONE PIECE).而航程中间,则是各式各样的 ...

  2. 我的JS 中级学习篇

    在codefordream上进入中级学习后,感觉立马从js的基础学习往前跳了好远,上面的东西好像都是第一次看到一样.这时候才发现,说来也曾接触过js,但是这时候才发现对js的认识就停在知道两点:js中 ...

  3. 详解JavaScript闭包

    要想完全明白JavaScript的闭包,要先明白js中的一些基础原理,然后我再给出一些例子来讲解闭包. 在执行JavaScript时会创建一个执行环境(excution context),执行环境定义 ...

  4. 利用jink的驱动软件j-flash 合并两个hex的方法,bootloader+app

    由于前几天要给工厂app和bootloader的hex的文件,网上很多都是bin的合并方法,bin的方法不再赘述,相信大家都能找到,现在将hex合并的方法写下来: 第一步:先打开第一个hex文件, 第 ...

  5. Redis【第二篇】集群搭建

    第一步:准备 1.安装包 ruby-2.4.0.tar.gz rubygems-2.6.10.tgz zlib-1.2.11.tar.gz redis-3.3.2.gem 2. 架构: 名称 IP 端 ...

  6. 2017.3.3自测j纠错题.

    解析:   在jUery中,他的背景颜色依次是红色,绿色,蓝色. 改变的是整个主体部分.<dody></body>. 单击. 2. 解析:  操作元素: html()  获取第 ...

  7. 2017-02-23 switch case 循环语句

    另一个分支语句:switch..case.. switch(变量){    case 值:代码段;break;    case 值:代码段;break;    ...    default:代码段;b ...

  8. JS入门(三)

    数据的类型转换: 之前提到过,js中数据类型分两种, 基本数据类型string  number   boolean  undefined  null 复杂数据类型 对象   Date   Array ...

  9. 1934: [Shoi2007]Vote 善意的投票

    1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 1174  Solved: 723[Submit][S ...

  10. UIImagePickerController拍照/相册/录像/本地视频

    1.导入系统库 #import <MobileCoreServices/MobileCoreServices.h> 2.遵守协议 <UIImagePickerControllerDe ...