Java多线程中对CountDownLatch的使用
1、CountDownLatch和CyclicBarrier作用
CountDownLatch和CyclicBarrier都位于java.util.concurrent包中,都具有计数功能,一般用于多线程间的协作。
CountDownLatch是减法计数器,子线程中调用countDown()计数减1,主线程调用await()阻塞线程执行,直到计数为0才会让线程继续执行,CountDownLatch不可重复利用。
CyclicBarrier是加法计数器,子线程调用await()计数加1,同时阻塞线程执行,直到兄弟线程都执行了await(),计数到达了设定值,CyclicBarrier可重复使用,计数到达指定值后重新开始。CyclicBarrier构造函数设定一个Runnable参数,通知计数已到达指定值。
2、使用示例
package com.zhi.test; import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier; import org.junit.Test; /**
* CyclicBarrier和CountDownLatch使用样例
*
* @author 张远志
* @since 2020年5月4日18:01:00
*
*/
public class MyTest {
@Test
public void test() {
int jobCount = 5;
CountDownLatch latch = new CountDownLatch(jobCount);
CyclicBarrier barrier = new CyclicBarrier(jobCount, new Runnable() {
public void run() {
System.out.println("所有线程都到了");
}
});
for (int i = 1; i <= jobCount; i++) {
new Thread(new Job(latch, barrier, i)).start();
}
try {
latch.await();
} catch (Exception e) {
}
System.out.println("所有线程已执行完成!");
} class Job implements Runnable {
private CountDownLatch latch;
private CyclicBarrier barrier;
private final int id; public Job(CountDownLatch latch, CyclicBarrier barrier, int id) {
this.latch = latch;
this.barrier = barrier;
this.id = id;
} @Override
public void run() {
try {
Thread.sleep(new Random().nextInt(10) * 1000);
System.out.println("线程" + id + "到达栅栏1");
barrier.await();
} catch (Exception e) {
}
try {
System.out.println("线程" + id + "到达栅栏2");
barrier.await();
} catch (Exception e) {
}
System.out.println("任务" + id + "执行完成");
latch.countDown();
}
}
}
执行结果:
线程2到达栅栏1
线程4到达栅栏1
线程5到达栅栏1
线程3到达栅栏1
线程1到达栅栏1
所有线程都到了
线程1到达栅栏2
线程2到达栅栏2
线程5到达栅栏2
线程4到达栅栏2
线程3到达栅栏2
所有线程都到了
任务3执行完成
任务1执行完成
任务2执行完成
任务4执行完成
任务5执行完成
所有线程已执行完成!
3、如何保证计数的线程安全性
CountDownLatch的countDown会进行加法计数,CyclicBarrier的await()会进行加法计数,查看源码我们会发现,这2个方法都没有使用synchronized关键字,那他们有时如何保证线程安全性的呢?
查看CountDownLatch源码,我们看到CountDownLatch使用了Sync内部类(继承AbstractQueuedSynchronizer)做减法,通过Unsafe类比较并设置新值。


查看CyclicBarrier源码,我们看到ReentrantLock锁。为啥它与CountDownLatch不一样呢,因为CyclicBarrier不仅要完成计数,还需要调用barrierCommand,并且要实现重复可用(将count值还原),其实ReentrantLock内部也使用Unsafe类进行了原子操作。

Java多线程中对CountDownLatch的使用的更多相关文章
- java多线程系列(八)---CountDownLatch和CyclicBarrie
CountDownLatch 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线 ...
- java多线程中最佳的实践方案是什么?
java多线程中最佳的实践方案是什么? 给你的线程起个有意义的名字.这样可以方便找bug或追踪.OrderProcessor, QuoteProcessor or TradeProcessor 这种名 ...
- java多线程中的三种特性
java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...
- java 多线程中的wait方法的详解
java多线程中的实现方式存在两种: 方式一:使用继承方式 例如: PersonTest extends Thread{ String name; public PersonTest(String n ...
- java多线程中并发集合和同步集合有哪些?区别是什么?
java多线程中并发集合和同步集合有哪些? hashmap 是非同步的,故在多线程中是线程不安全的,不过也可以使用 同步类来进行包装: 包装类Collections.synchronizedMap() ...
- Java多线程中的常用方法
本文将带你讲诉Java多线程中的常用方法 Java多线程中的常用方法有如下几个 start,run,sleep,wait,notify,notifyAll,join,isAlive,current ...
- Java多线程中的竞争条件、锁以及同步的概念
竞争条件 1.竞争条件: 在java多线程中,当两个或以上的线程对同一个数据进行操作的时候,可能会产生“竞争条件”的现象.这种现象产生的根本原因是因为多个线程在对同一个数据进行操作,此时对该数据的操作 ...
- 深入浅出Java并发中的CountDownLatch
1. CountDownLatch 正如每个Java文档所描述的那样,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行.在Java并发中 ...
- Java多线程中的死锁
Java多线程中的死锁 死锁产生的原因 线程死锁是指由两个以上的线程互相持有对方所需要的资源,导致线程处于等待状态,无法往前执行. 当线程进入对象的synchronized代码块时,便占有了资源,直到 ...
随机推荐
- django认证系统 Authentication
Django自带一个用户认证系统,用于处理用户账户.群组.许可和基于cookie的用户会话. Django的认证系统包含了身份验证和权限管理两部分.简单地说,身份验证用于核实某个用户是否合法,权限管理 ...
- [转]fatal error LNK1112: 模块计算机类型“X86”与目标计算机类型“x64”冲突
来自--------------------- 原文:https://blog.csdn.net/qtbmp/article/details/7273191?utm_source=copy win7 ...
- java线程执行的优先级
1.1 线程的优先级 java 中的线程优先级的范围是1-10,默认的优先级是5.10极最高. 有时间片轮循机制.“高优先级线程”被分配CPU的概率高于“低优先级线程”.根据时间片轮循调度, ...
- 虚拟机上自动化部署(EFI网络安装)ESXi服务器遇到的问题
1,虚拟机的CPU为2核或以上. 2,虚拟机选项中不选择: 启用UEFI安全引导.3,引导延迟:设置3000毫秒或以上 4,#GP Exception 13 in world 1:unknown @ ...
- Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 在 ...
- Lua和C++交互 学习记录之五:全局数组交互
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...
- AtCoder Regular Contest 094 D Worst Case
Worst Case 思路: 使 a <= b 当 a == b 时 或者 a == b - 1 时,答案显然为 2 * (a - 1) 否则找到最大的 c ,使得 c * c < a * ...
- Asp.net core 学习笔记 (Excel 读写)
EPPlus 已经支持 .net core 了 https://www.nuget.org/packages/EPPlus https://github.com/JanKallman/EPPlus 写 ...
- ThinkPHP执行原生的SQL语句
执行原生的SQL语句: $sql="insert select update delete...."; ①查询语句: $model对象 -> query($sql); ...
- 并发之ThreadLocal
ThreadLocal ThreadLocal 用一种存储变量与线程绑定的方式,在每个线程中用自己的 ThreadLocalMap 安全隔离变量,为解决多线程程序的并发问题提供了一种新的思路. 简 ...