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的使用的更多相关文章

  1. java多线程系列(八)---CountDownLatch和CyclicBarrie

    CountDownLatch 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线 ...

  2. java多线程中最佳的实践方案是什么?

    java多线程中最佳的实践方案是什么? 给你的线程起个有意义的名字.这样可以方便找bug或追踪.OrderProcessor, QuoteProcessor or TradeProcessor 这种名 ...

  3. java多线程中的三种特性

    java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...

  4. java 多线程中的wait方法的详解

    java多线程中的实现方式存在两种: 方式一:使用继承方式 例如: PersonTest extends Thread{ String name; public PersonTest(String n ...

  5. java多线程中并发集合和同步集合有哪些?区别是什么?

    java多线程中并发集合和同步集合有哪些? hashmap 是非同步的,故在多线程中是线程不安全的,不过也可以使用 同步类来进行包装: 包装类Collections.synchronizedMap() ...

  6. Java多线程中的常用方法

    本文将带你讲诉Java多线程中的常用方法   Java多线程中的常用方法有如下几个 start,run,sleep,wait,notify,notifyAll,join,isAlive,current ...

  7. Java多线程中的竞争条件、锁以及同步的概念

    竞争条件 1.竞争条件: 在java多线程中,当两个或以上的线程对同一个数据进行操作的时候,可能会产生“竞争条件”的现象.这种现象产生的根本原因是因为多个线程在对同一个数据进行操作,此时对该数据的操作 ...

  8. 深入浅出Java并发中的CountDownLatch

      1. CountDownLatch 正如每个Java文档所描述的那样,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行.在Java并发中 ...

  9. Java多线程中的死锁

    Java多线程中的死锁 死锁产生的原因 线程死锁是指由两个以上的线程互相持有对方所需要的资源,导致线程处于等待状态,无法往前执行. 当线程进入对象的synchronized代码块时,便占有了资源,直到 ...

随机推荐

  1. java.io.FileNotFoundException异常,一是“拒绝访问”,二是“系统找不到指定路径”

    关于java.io.FileNotFoundException异常 因为这个异常抛出俩种情况:一是“拒绝访问”,二是“系统找不到指定路径” 这里只讲明什么时候抛拒绝访问,什么时候抛找不到指定路径. 原 ...

  2. 大话WebRTC的前世今生

    音视频的历史 音视频可以说是人类与生俱来的需求,人一出生就要用耳朵听,用眼睛看.中国的古代神话中为此还专门设置了两位神仙(千里眼和顺风耳),他们可以听到或看到千里之外的声音或景像. 为了解决听的远和看 ...

  3. highchart柱状堆叠图动态数据请求

    $(function () { var options = { chart: { renderTo: 'indoor', type: 'column', }, title: { text: '室内问题 ...

  4. 2017-2018-2 20165327 实验二 《Java面向对象程序设计》实验报告

    20165327<Java程序设计>实验二 <Java面向对象程序设计>实验报告 实验二 <Java面向对象程序设计> 一.实验报告封面 课程:Java程序设计 班 ...

  5. Juniper基础配置

    root> show configuration | display set      配置按set行显示,查看的配置为未commit的配置(commit check)root# set sys ...

  6. 20170906xlVBA_CopyDataAndFormatFromSheets

    Public Sub GatherDataInSameWorkbook() AppSettings ' On Error GoTo ErrHandler Dim StartTime, UsedTime ...

  7. linux bash基本特性

    一.bash 基础特性 (1)命令历史的功能 history: 环境变量 HISTSIZE:命令历史记录的条数 HISTFILE: ~/.bash_history 每个用户都有自己独立的命令历史文件 ...

  8. Two Melodies CodeForces - 813D (DP,技巧)

    https://codeforces.com/problemset/problem/813/D dp[i][j] = 一条链以i结尾, 另一条链以j结尾的最大值 关键要保证转移时两条链不能相交 #in ...

  9. 『TensorFlow』SSD源码学习_其四:数据介绍及TFR文件生成

    Fork版本项目地址:SSD 一.数据格式介绍 数据文件夹命名为VOC2012,内部有5个子文件夹,如下, 我们的检测任务中使用JPEGImages文件夹和Annotations文件夹. JPEGIm ...

  10. shiro中SSL

    对于SSL的支持,Shiro只是判断当前url是否需要SSL登录,如果需要自动重定向到https进行访问. 首先生成数字证书,生成证书到D:\localhost.keystore 使用JDK的keyt ...