Java多线程下循环计数器

本文主要内容:CyclicBarrier(下文中凯哥就用cycBar来代替)定义介绍;举例说明;代码演示;从源码来看原理及总结;CyclicBarrier与CountDownLatch(下文就用CountDown来代替)比较。

本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《并发工具类》教程的第二篇:《Java多线程下循环计数器》。

编辑

一:CyclicBarrier是什么

cycBar是什么呢?

来看看JDKAPI文档中是怎么介绍这个对象的:

翻译后大概意思:允许一组线程全部等待彼此达到共同的屏障点的同步辅助。循环阻塞在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此。屏障被称为循环 ,因为它可以在等待的线程被释放之后重新使用。

有没有这种感觉:每个汉字都认识,但是放在一起就不知道什么意思了?对!没错,就是这种感觉~~~///(^v^)\\\~~~。上面翻译简单一句话就是:有个可以循环利用的集合点。作用就是让所有线程都到达这个集合点后,才会继续下一步行动。如果还是不理解,请看下下面生活中的例子。

二:CyclicBarrier生活中例子理解

在生活中,如果我们跟团旅游的话,就更容易理解了。假设一个团有7个人,旅游团安排的旅游路线是八达岭长城故宫这个路线的一日游。游玩时间是3小时。三个小时后, 统一都到八达岭的集合点:入口处。点名等人员都到齐后,发车到下一个景点。这种场景相信大家都遇到过吧。八达岭入口的集合点不仅仅这个旅游团可以使用,其他的旅游团都可以使用的。如果站在多线程并发场景下来分析的话:旅游团中每个成员都是一个线程,入口集合点就是屏障(Barrier),每个成员都必须到达集合点(循环到达Cyclic)且人数和旅游团人数相等的时候,才能触发旅游车发车去下一个景点的线程。

还有一个例子更容易理解:集齐七龙珠,召唤神龙。相信看过《七龙珠》的都知道这个吧。想要召唤神龙的触发点就是集齐七个龙珠。

通过上面案例,大家是不是更容易理解了?下面凯哥(kaigejava)将通过代码实现集齐七龙珠召唤神龙的操作。

三:代码演示

需求:集齐七颗龙珠,召唤神龙。

3.1:未使用cycbarr的时候

使用七个线程,来代替找龙珠的七个任务。每个线程在找龙珠的时候,耗时2s.就sleep。最后,七个线程执行完成之后,使用召唤神龙的线程来召唤神龙。代码如下图:

运行结果:

我们发现,龙珠还没有找到呢,神龙就出现了。这个当然是不对的。所以不使用cycBarr这个操作是不对的。

3.2:使用cycbarr

查看运行结果:

当七颗龙珠都找到之后,才可以召唤神龙。 符合我们的需求。那么,cycbarr的实现原理是什么呢?接下来我们从源码来看看运行原理。

四:从源码来看原理及总结

4.1:构造器

有两个构造器,给定一个int的parties和两个参数的构造器。参数含义:

Int parties:给定参与的线程的个数。也可以理解为屏障的值,当达到这个值之后,屏障将会跳闸执行其他任务(在集齐龙珠案例中,可以理解为需要7个线程来执行。);

Runnable barrierAction:这个参数意思是指当线程达到屏障数量后,屏障跳闸后执行给定线程的任务(在集齐龙珠案例中,可以理解为当集齐七颗龙珠后,需要执行召唤神龙的操作)。

4.2:几个重要的成员属性

其中使用了ReentrantLock这个可重入锁作为并发的锁对象。使用Codition这个对象来实现等待/通知模式。

4.3:重要方法

无论是await()还是await(long timeout,TimeUnit unit)这两个await最后都是调用dowait()方法。

Dowait方法主要干了什么?其实逻辑处理比较简单的。如果当前线程不是最后一个调用await方法的线程,则会一直自旋等待着。源码如下:

当发生以下清空的时候,就会在自旋等待了:

1:当前执行的线程是最后一个线程。即index == 0成立的时候;

2:当参与其中的某个线程在等待的时候,等待超时了;

3:参与的线程中某一个线程被中断了;

4:在调用了CycBarr的reset方法后。该方法将会将对应的屏障(parties)重置为初始状态。

对应源码如下:

4.4:总结

语法:

默认使用两个参数的构造器。然后再try代码块中调用await方法。如下图:

五:CyclicBarrier与CountDownLatch比较

关于CountDownLatch的相关介绍,凯哥(kaigejava)在另一篇文章《Java多线程并发容器之并发倒计时器》中做了详细介绍。欢迎大家去查看.

CountDown:

计数器只能够使用一次;

参与的线程的职责是不一样的(火箭发射,不同部门做的事情不一样)。有的再倒计时,有的再等待倒计时结束。

CycBarr:

是可以循环利用的,因为可以使用reset方法将屏障重置,可以使用多次,所有cycBar能够处理更为复杂的场景;

参与的线程职责是一样的(都是找龙珠);

提供了其他的方法。如获取当前阻塞的线程数量的getnumberWaiting方法。用于判断当前线程阻塞的线程是否被中断的isBroken方法。

从唤起阻塞线程角度来看的话:

CountDownLatch运行一个或者是多个线程等待一组事件的产生,而CyclicBarrier用于等待其他线程运行到屏障(栅栏)位置。

从适用场景角度来说:

CycBarr适用于多个线程结果元素的合并操作。

如需要从多个excel中统计数量的时候,可以使用CycBarr来从不同的excel读取到数据之后,在进行汇总操作。

​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​欢迎来聊

Java多线程工具类之循环栅栏计数器的更多相关文章

  1. 线程工具类 - CyclicBarrier(循环栅栏)

    CyclicBarrier官方文档 一.原理 CyclicBarrier是另外一种多线程并发控制实用工具.它和CountDownLatch非常类似,它也可以实现线程的计数等待,但它的功能比CountD ...

  2. 25.大白话说java并发工具类-CountDownLatch,CyclicBarrier,Semaphore,Exchanger

    1. 倒计时器CountDownLatch 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join ...

  3. 基于AQS实现的Java并发工具类

    本文主要介绍一下基于AQS实现的Java并发工具类的作用,然后简单谈一下该工具类的实现原理.其实都是AQS的相关知识,只不过在AQS上包装了一下而已.本文也是基于您在有AQS的相关知识基础上,进行讲解 ...

  4. Java并发工具类 - CountDownLatch

    Java并发工具类 - CountDownLatch 1.简介 CountDownLatch是Java1.5之后引入的Java并发工具类,放在java.util.concurrent包下面 http: ...

  5. Java 文件下载工具类

    Java 文件下载工具类 import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static Logger logger = ...

  6. Java Properties工具类详解

    1.Java Properties工具类位于java.util.Properties,该工具类的使用极其简单方便.首先该类是继承自 Hashtable<Object,Object> 这就奠 ...

  7. Java json工具类,jackson工具类,ObjectMapper工具类

    Java json工具类,jackson工具类,ObjectMapper工具类 >>>>>>>>>>>>>>> ...

  8. Java日期工具类,Java时间工具类,Java时间格式化

    Java日期工具类,Java时间工具类,Java时间格式化 >>>>>>>>>>>>>>>>>&g ...

  9. MinerUtil.java 爬虫工具类

    MinerUtil.java 爬虫工具类 package com.iteye.injavawetrust.miner; import java.io.File; import java.io.File ...

随机推荐

  1. EF多租户实例:如何快速实现和同时支持多个DbContext

    前言 上一篇随笔我们谈到了多租户模式,通过多租户模式的演化的例子.大致归纳和总结了几种模式的表现形式. 并且顺带提到了读写分离. 通过好几次的代码调整,使得这个库更加通用.今天我们聊聊怎么通过该类库快 ...

  2. 小白学 Python 数据分析(15):数据可视化概述

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  3. Simulink仿真入门到精通(十三) Simulink创建自定义库

    当用户自定义了一系列模块之后,可以自定义模块库将同类自定义模块显示到Simulink Browser中,作为库模块方便地拖曳到新建模型中. 建立这样的自定义库需要3个条件: 建立library的mdl ...

  4. Markdown试用

    目录 今天又是充满希望的一天 一.是什么 二.为什么 三.怎么做 代码 这世界上好人坏人都很多,我不是一个坏人. 我不是个英雄,我只是个拿

  5. 微信小程序开发(一)开发准备

    微信小程序开发(一)开发准备 微信小程序,近几年,越来越火,应用场景越来越多,好大学习起来,比较容易,学习曲线平缓,你要是会前端开发,那简直可以用易如反掌来形容. 小程序,开发工具官方也提供了,他兼容 ...

  6. 我的MacbookPro进水了!维修过程记录

    电脑进水与解决方案 如果事情有变坏的可能,不管这种可能性有多小,它总会发生.---墨菲定律 进水过程 2020年03月21日日下午3点左右,不小心把水杯碰倒了,水通过电脑右侧的键盘处进入了大概有10毫 ...

  7. Python3之turtle的基本用法#Python学习01#

    一.turtle基本语法 1.导入turtle 模块import turtle 2.显示箭头turtle.showturtle() 3.写字符串turtle.write("因小米" ...

  8. JSP+Servlet+C3P0+Mysql实现的网上蛋糕店

    本文存在视频版本,请知悉 项目简介 项目来源于:https://gitee.com/PositiveMumu/CakesShop/tree/master 这次分享一个蛋糕商场系统,还是很简单的系统.界 ...

  9. hdu1026Ignatius and the Princess ,又要逃离迷宫了

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1026/ 题意就是一个迷宫,然后有些位置上有守卫,守卫有一个血量,要多花费血量的时间击败他,要求从(0,0)到(n ...

  10. Servlet(四)----HTTP、Response、servletContent

    ##  HTTP协议: 1.请求消息:客户端发送给服务器端的数据 *  数据格式: 1.请求行 2.请求头     3.请求空行 4.请求体 2.响应消息:服务器端发送给客户端的数据 *  数据格式: ...