CountDownLatch和CyclicBarrier的功能看起来很相似,不易区分,有一种谜之的神秘。本文将通过通俗的例子并结合代码讲解两者的使用方法和区别。

CountDownLatch和CyclicBarrier都是java.util.concurrent包下面的多线程工具类。

从字面上理解,CountDown表示减法计数,Latch表示门闩的意思,计数为0的时候就可以打开门闩了。Cyclic Barrier表示循环的障碍物。两个类都含有这一个意思:对应的线程都完成工作之后再进行下一步动作,也就是大家都准备好之后再进行下一步。然而两者最大的区别是,进行下一步动作的动作实施者是不一样的。这里的“动作实施者”有两种,一种是主线程(即执行main函数),另一种是执行任务的其他线程,后面叫这种线程为“其他线程”,区分于主线程。对于CountDownLatch,当计数为0的时候,下一步的动作实施者是main函数;对于CyclicBarrier,下一步动作实施者是“其他线程”。

下面举例说明:

对于CountDownLatch,其他线程为游戏玩家,比如英雄联盟,主线程为控制游戏开始的线程。在所有的玩家都准备好之前,主线程是处于等待状态的,也就是游戏不能开始。当所有的玩家准备好之后,下一步的动作实施者为主线程,即开始游戏。

我们使用代码模拟这个过程,我们模拟了三个玩家,在三个玩家都准备好之后,游戏才能开始。代码的输出结果为:

正在等待所有玩家准备好

player0 已经准备好了, 所使用的时间为 1.235s

player2 已经准备好了, 所使用的时间为 1.279s

player3 已经准备好了, 所使用的时间为 1.358s

player1 已经准备好了, 所使用的时间为 2.583s

开始游戏

1

2

3

4

5

6

CountDownLatch的代码:

import java.util.Random;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest {

public static void main(String[] args) throws InterruptedException {

CountDownLatch latch = new CountDownLatch(4);

for(int i = 0; i < latch.getCount(); i++){

new Thread(new MyThread(latch), "player"+i).start();

}

System.out.println("正在等待所有玩家准备好");

latch.await();

System.out.println("开始游戏");

}

private static class MyThread implements Runnable{

private CountDownLatch latch ;

public MyThread(CountDownLatch latch){

this.latch = latch;

}

@Override

public void run() {

try {

Random rand = new Random();

int randomNum = rand.nextInt((3000 - 1000) + 1) + 1000;//产生1000到3000之间的随机整数

Thread.sleep(randomNum);

System.out.println(Thread.currentThread().getName()+" 已经准备好了, 所使用的时间为 "+((double)randomNum/1000)+"s");

latch.countDown();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

对于CyclicBarrier,假设有一家公司要全体员工进行团建活动,活动内容为翻越三个障碍物,每一个人翻越障碍物所用的时间是不一样的。但是公司要求所有人在翻越当前障碍物之后再开始翻越下一个障碍物,也就是所有人翻越第一个障碍物之后,才开始翻越第二个,以此类推。类比地,每一个员工都是一个“其他线程”。当所有人都翻越的所有的障碍物之后,程序才结束。而主线程可能早就结束了,这里我们不用管主线程。

我们使用代码来模拟上面的过程。我们设置了三个员工和三个障碍物。可以看到所有的员工翻越了第一个障碍物之后才开始翻越第二个的,下面是运行结果:

main function is finished.

队友1, 通过了第0个障碍物, 使用了 1.432s

队友0, 通过了第0个障碍物, 使用了 1.465s

队友2, 通过了第0个障碍物, 使用了 2.26s

队友1, 通过了第1个障碍物, 使用了 1.542s

队友0, 通过了第1个障碍物, 使用了 2.154s

队友2, 通过了第1个障碍物, 使用了 2.556s

队友1, 通过了第2个障碍物, 使用了 1.426s

队友2, 通过了第2个障碍物, 使用了 2.603s

队友0, 通过了第2个障碍物, 使用了 2.784s

1

2

3

4

5

6

7

8

9

10

代码:

package com.huai.thread;

import java.util.Random;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest {

public static void main(String[] args) {

CyclicBarrier barrier = new CyclicBarrier(3);

for(int i = 0; i < barrier.getParties(); i++){

new Thread(new MyRunnable(barrier), "队友"+i).start();

}

System.out.println("main function is finished.");

}

private static class MyRunnable implements Runnable{

private CyclicBarrier barrier;

public MyRunnable(CyclicBarrier barrier){

this.barrier = barrier;

}

@Override

public void run() {

for(int i = 0; i < 3; i++) {

try {

Random rand = new Random();

int randomNum = rand.nextInt((3000 - 1000) + 1) + 1000;//产生1000到3000之间的随机整数

Thread.sleep(randomNum);

System.out.println(Thread.currentThread().getName() + ", 通过了第"+i+"个障碍物, 使用了 "+((double)randomNum/1000)+"s");

this.barrier.await();

} catch (InterruptedException e) {

e.printStackTrace();

} catch (BrokenBarrierException e) {

e.printStackTrace();

}

}

}

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

总结:CountDownLatch和CyclicBarrier都有让多个线程等待同步然后再开始下一步动作的意思,但是CountDownLatch的下一步的动作实施者是主线程,具有不可重复性;而CyclicBarrier的下一步动作实施者还是“其他线程”本身,具有往复多次实施动作的特点。

Java的CountDownLatch和CyclicBarrier的理解和区别的更多相关文章

  1. java 并发包JUC下的CountDownLatch和CyclicBarrier的理解和区别

    推荐这篇帖子,讲得不错~ https://blog.csdn.net/liangyihuai/article/details/83106584

  2. CountDownLatch、CyclicBarrier、Semaphore的区别

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就学习一下这三个辅助类的用法. 以下是 ...

  3. 使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法 一.C ...

  4. Java中CountDownLatch和CyclicBarrier的使用和比较

    CountDownLatch和CyclicBarrier同为Java1.5开始引入的,应用于多线程编程中的一种工具,二者用途十分相近,十分容易混淆. CountDownLatch CountDownL ...

  5. java并发--CountDownLatch、CyclicBarrier和Semaphore

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下 ...

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

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

  7. java面试-CountDownLatch、CyclicBarrier、Semaphore谈谈你的理解

    一.CountDownLatch 主要用来解决一个线程等待多个线程的场景,计数器不能循环利用 public class CountDownLatchDemo { public static void ...

  8. Java中CountDownLatch和CyclicBarrier

    Java编程思想中的例子import javax.validation.constraints.Size; import java.util.Random; import java.util.conc ...

  9. CountDownLatch和CyclicBarrier使用上的区别

    一.CountDownLatchDemo package com.duchong.concurrent; import java.util.Map; import java.util.concurre ...

随机推荐

  1. SQL Server中调用WebService

    首先要启用Ole Automation Procedures,使用sp_configure 配置时如果报错"不支持对系统目录进行即席更新",可以加上WITH OVERRIDE选项. ...

  2. maven编译项目报错,提示找不到符号或程序包XXX不存在

    我的原因是maven依赖的jar包都下载了,但是引用的同一个项目下其他模块jar包找不到 解决方法: 把需要的jar包在pom里添加依赖 再次运行项目,Maven Dependencies下就会多了几 ...

  3. 如何解决win10关机状态下,按键盘会自动开机的问题

    关机状态下按下键盘会自动开机,是因为所装的系统默认设置了快速启动功能 下面是关闭快速启动的方法: 步骤一: 在win10桌面右击,点击显示设置 步骤二: 电源和睡眠-->其他电源设置 步骤三: ...

  4. ucos ii 46个系统API函数解析

    源: ucos ii 46个系统API函数解析

  5. Oracle之现有表上建新表、操作符、字符函数

    #PLSQL技术培训15页PPT利用现有表创建表(百度) 说明:做新操作前要对旧表备份  具体百度 语法: create table <new_table_name> as select ...

  6. Docker学习笔记之Docker 的简历

    0x00 概述 在了解虚拟化和容器技术后,我们就更容易理解 Docker 的相关知识了.在这一小节中,我将介绍关于 Docker 的出现和发展,Docker 背后的技术.同时,我们将阐述 Docker ...

  7. django F表达式、Q表达式、annotate、order_by

    如下模型: class Book(models.Model): name = models.CharField(max_length=100) pages = models.IntegerField( ...

  8. 标准库 string

    1.func Fields(s string) []string,这个函数的作用是按照1:n个空格来分割字符串最后返回的是[]string的切片 package main import ( " ...

  9. bzoj 1295 最长距离 - 最短路

    Description windy有一块矩形土地,被分为 N*M 块 1*1 的小格子. 有的格子含有障碍物. 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离. 如果从格 ...

  10. Codeforces 837E Vasya's Function - 数论

    Vasya is studying number theory. He has denoted a function f(a, b) such that: f(a, 0) = 0; f(a, b) = ...