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代码块时,便占有了资源,直到 ...
随机推荐
- python 加密
https://github.com/duanhongyi/gmssl
- ros 充电topic
#!/usr/bin/env python #coding=utf- import rospy from std_msgs.msg import String i= def talker(): glo ...
- python 安装pip
https://pip.pypa.io/en/stable/installing/
- Eclipse调试DEBUG时快速查看某个变量的值的快捷键、快速跳转到某行的快捷键
Eclipse调试DEBUG时快速查看某个变量的值的快捷键 Ctrl + Shift + i
- ppython的移位操作
因为要将js的一个签名算法移植到python上,遇到一些麻烦. int无限宽度,不会溢出 算法中需要用到了32位int的溢出来参与运算,但是python的int是不会溢出的,达到界限后会自己转为lon ...
- VC静态调用DLL(lib)
1. #pragma comment(lib, "libxml2.lib")#pragma comment(lib, "iconv.lib")#pragma c ...
- Spring Bean的生命周期例子
以下例子源于:W3Cschool,在此作记录 HelloWorld.java package com.how2java.w3cschool.beanlife; public class HelloWo ...
- 基于Arcface 免费离线人脸识别 2.0 Demo C#
本来打算做个C#版demo,但没用成功.使用虹软最新人脸识别技术开发完成 过程如下: 1. 传入一张单人脸照片: 2.调用检测人脸函数ASFDetectFaces,成功返回人脸信息的指针: 3.使用 ...
- Spring Cloud 入门教程(一): 服务注册
1. 什么是Spring Cloud? Spring提供了一系列工具,可以帮助开发人员迅速搭建分布式系统中的公共组件(比如:配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁 ...
- ip网关配置
流量查看watch more /proc/net/devip子网查询https://www.sojson.com/convert/subnetmask.htmlhttp://ip.gchao.cn/ ...