线程基础、线程之间的共享和协作

(目前会将一些概念简单描述,一些重点的点会详细描述)

学习目标:多线程的并发工具类(3)

CountDownLatch、CyclicBarrier

一、CountDownLatch

官方介绍:

CountDownLatch是在java1.5被引入的,它存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。

CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

什么意思呢?就是运行过程中,有几个线程,那么只有当几个线程同时就绪之后,类似于100米赛跑一样,必须所有运动员到达起跑线之后,通过一个发令枪才能够一起冲向终点,运行起来。

里面就有几个方法,分别介绍一下:

countDown()方法:该方法初始值设置为允许运行的线程数,这里比如赛道上只能容纳10个人,则初始值为10,然后每一次线程执行完,则将初始值10减1,一直减到0为止,然后表示所有的运动员都就位了,然后就等待发令枪声响就开始同时运行了。这里要注意的点是,必须在每一个线程执行完之后,调用countDown()方法,否则数据将出错!

await()方法:该方法就相当于发令枪,当判断countDown()将初始值一直减到0 之后,表示所有的线程已经就绪了,就执行await()方法,所有线程就开始同时执行后续操作。

下面来看代码:

import java.util.concurrent.CountDownLatch;import com.xiangxue.tools.SleepTools;/*** CountDownLatch工具类使用* * @author xgx*/
public class UseCountDownLatch {// 定义总共有7个球private static final int ALL_SEVEN_BALL = 7;// 实例化CountDownLatch类private static CountDownLatch countDownLatch = new CountDownLatch(ALL_SEVEN_BALL);/*** 调用CountDownLatch实例* * @param args* @throws InterruptedException*/public static void main(String[] args) throws InterruptedException {for (int i = 1; i <= ALL_SEVEN_BALL; i++) {Thread thread = new Thread(new SubCountDownLatch());thread.start();}// 当所有线程已经执行完毕,调用await()方法,将同时线程置于非阻塞状态,执行后续的业务countDownLatch.await();System.out.println("已经成功集齐7色球!恭喜中大奖!");}// 定义CountDownLatch多线程类,表示这个类要做什么事情private static class SubCountDownLatch implements Runnable {// 所有7个线程countDown()方法没有把总数减为0时,都将阻塞,当通过countDown()方法将数量减到0时,则所有的线程都已经执行完毕,进行输出public void run() {// 这里输出我意思了一下。至于为什么Thread.currentThread().getId()是从10开始的,自行百度,这里不多说。System.out.println("已经搜集到了第: " + (Long.valueOf(Thread.currentThread().getId()) - 9) + " 个球");SleepTools.ms(1000);countDownLatch.countDown();}}
}控制台输出结果:
已经搜集到了第: 6 个球
已经搜集到了第: 5 个球
已经搜集到了第: 4 个球
已经搜集到了第: 2 个球
已经搜集到了第: 7 个球
已经搜集到了第: 3 个球
已经搜集到了第: 1 个球
已经成功集齐7色球!恭喜中大奖!

我们看到,所有线程都是按照顺序来执行的,没有出现线程不安全结果。

二、CyclicBarrier

官方介绍:

CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到所有线程都到达某个公共屏障点(也可以叫同步点),即相互等待的线程都完成调用await方法,所有被屏障拦截的线程才会继续运行await方法后面的程序。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时CyclicBarrier很有用。因为该屏障点在释放等待线程后可以重用,所以称它为循环的屏障点。CyclicBarrier支持一个可选的Runnable命令,在一组线程中的最后一个线程到达屏障点之后(但在释放所有线程之前),该命令只在所有线程到达屏障点之后运行一次,并且该命令由最后一个进入屏障点的线程执行。

什么意思呢?CyclicBarrier强调的是n个线程,大家相互等待,只要有一个没完成,所有人都得等着。还是举上面的例子,这次就是得7个人,然后去买cai票,然后等最后一个买完,7个人都到一起之后(这里说到达屏障点之后),就可以运行后续的程序了。

来看实现代码:

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;/*** CyclicBarrier工具类使用* * @author xgx*/
public class UseCyclicBarrier {// 定义总共有7个球private static final int ALL_SEVEN_BALL = 7;// 定义CyclicBarrier对象private static CyclicBarrier cyclicBarrier = new CyclicBarrier(ALL_SEVEN_BALL, new ResultCyclicBarrier());// 主方法public static void main(String[] args) {for (int i = 0; i < ALL_SEVEN_BALL; i++) {Thread thread = new Thread(new OperateCyclicBarrier());thread.start();}}// 定义一个最终结果的类private static class ResultCyclicBarrier implements Runnable {public void run() {// 调用操作类,然后都在屏障点等候new OperateCyclicBarrier();// 当ALL_SEVEN_BALL个人都已经成功操作完成之后,在执行后续业务System.out.println("已经成功集齐7色球!恭喜中大奖!");}}// 定义一个ALL_SEVEN_BALL个数线程操作类private static class OperateCyclicBarrier implements Runnable {// 做ALL_SEVEN_BALL个数的事情public void run() {try {System.out.println("第:" + Long.valueOf(Thread.currentThread().getId() - 9) + " 个人开始出发收集七色球!!!");Thread.sleep(new Random().nextInt(3000));// 所有的线程全部到达屏障点之前,都处于阻塞状态cyclicBarrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}}
}控制台输出结果:
第:2 个人开始出发收集七色球!!!
第:6 个人开始出发收集七色球!!!
第:3 个人开始出发收集七色球!!!
第:1 个人开始出发收集七色球!!!
第:4 个人开始出发收集七色球!!!
第:7 个人开始出发收集七色球!!!
第:5 个人开始出发收集七色球!!!
已经成功集齐7色球!恭喜中大奖!

三、CountDownLatch和CyclicBarrier的区别

(1)CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次。(这里CyclicBarrier更多的方法这里后兴趣的朋友可以自行研究)

(2)CyclicBarrier还提供其他有用的方法,比如getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量。isBroken方法用来知道阻塞的线程是否被中断。比如以下代码执行完之后会返回true。

(3)CountDownLatch会阻塞主线程,CyclicBarrier不会阻塞主线程,只会阻塞子线程。

(4)CountDownLatch依靠一个外力(计数器,发令枪)来控制线程,而CyclicBarrier是相当于本身来控制线程,举个例子:

CountDownLatch:有个装满宝石的房间,门外有7把锁,然后有7个人要进入房间组成队伍A,还有另外7个人手里拿着钥匙组成队伍B,那么首先的A组7人必须等到B组7人把钥匙送过来,然后把门外7把锁给分别打开后,这A组7人才能够进入房间拿到宝石。

CyclicBarrier:有个装满宝石的房间,门外也有7把锁,然后这7个人必须到另外一个房间,各自完成一个任务,然后每个人才能够获得一把锁,完成任务之后,这7个人就能够打开那7把锁,然后拿到宝石。

因为时间有限,每天晚上只能总结一点,因此希望能够理解思想,继续学习进步!!

更多精彩敬请关注公众号

Java极客思维

微信扫一扫,关注公众号

多线程学习-day-07CountDownLatch、CyclicBarrier相关推荐

  1. java多线程学习-java.util.concurrent详解

    http://janeky.iteye.com/category/124727 java多线程学习-java.util.concurrent详解(一) Latch/Barrier 博客分类: java ...

  2. java线程集合点_Java多线程学习笔记(三) 甚欢篇

    使人有乍交之欢,不若使其无久处之厌 <小窗幽记>很多时候,我们需要的都不是再多一个线程,我们需要的线程是许多个,我们需要让他们配合.同时我们还有一个愿望就是复用线程,就是将线程当做一个工人 ...

  3. java多线程学习笔记。

    java多线程学习笔记 线程的优缺点: 多线程的好处: 充分利用多处理核心,提高资源的利用率和吞吐量. 提高接口的响应效率,异步系统工作. 线程的风险: 安全危险(竞争条件):什么坏事都没有发生.在没 ...

  4. java线程学习,GitHub - zksir/thread: Java多线程学习

    Java多线程学习 threadcoreknowledge包----线程核心知识基础 createthreads包 创建线程 1.实现多线程的方法是1种还是2种还是4种? Oracle官方:2种,一种 ...

  5. java多线程学习之【Exchanger】

    目前卷文化盛行,为了增强面试能力,开始了无边无际的学习,无边界不是重点,重点是要深入1万米.言归正传,本文打算做一个多线程学习的系列文章,沉淀自我. 文章目录 前言 一.Exchanger是什么? 二 ...

  6. Java多线程学习处理高并发问题

    在程序的应用程序中,用户或请求的数量达到一定数量,并且无法避免并发请求.由于对接口的每次调用都必须在返回时终止,因此,如果接口的业务相对复杂,则可能会有多个用户.调用接口时,该用户将冻结. 以下内容将 ...

  7. C#多线程学习(四) 多线程的自动管理(线程池) (转载系列)——继续搜索引擎研究...

    在多线程的程序中,经常会出现两种情况: 一种情况:   应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应                   这一般使用ThreadPo ...

  8. 艾伟:C#多线程学习(六) 互斥对象

    本系列文章导航 C#多线程学习(一) 多线程的相关概念 C#多线程学习(二) 如何操纵一个线程 C#多线程学习(三) 生产者和消费者 C#多线程学习(四) 多线程的自动管理(线程池) C#多线程学习( ...

  9. C# 多线程学习总结

    C#多线程学习(一) 多线程的相关概念 什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程? 线程是 ...

最新文章

  1. 浅谈单片机程序设计中的“分层思想”
  2. ubuntu 关闭显示,关闭显卡,命令与图形切换
  3. 利用异步I/O复制文件及详解
  4. 错误记录,找不到sqlite dll
  5. echarts时间轴传什么格式_职场必看,使用Excel实现大事件时间轴的做法,不看后悔...
  6. mysql中间件研究(Atlas,cobar,TDDL,Mycat)
  7. 幻灯片形式设计:从方法到技巧
  8. [转]Linq查询DataTable,DataRow
  9. 解决VisualStudio2008下asp.net mvc开发向View中添加服务器控件崩溃的问题
  10. ImportError: libcudart.so.9.2: cannot open shared object file: No such file or directory
  11. JExcel - 学习总结(1)
  12. Kafka权威指南-学习笔记---第一章
  13. Expandable Button
  14. SkinH皮肤使用教程,及皮肤效果测试工具
  15. 《面试无忧》--DCL单例模式为什么要用volatile修饰?
  16. MCU-51:单片机蜂鸣器播放音乐和提示音
  17. java的起源于诞生!
  18. 三星530换固态硬盘_轻巧便捷,精致高颜—三星T7 PSSD使用评测_固态硬盘
  19. 皮皮_ssl2542_并查集
  20. 潍坊学院c语言试卷,潍坊学院《机械设计》试卷(A卷)答案及评分标准

热门文章

  1. 理解Java ClassLoader机制 |用Java说话,人气战胜时间!Come On
  2. erp与相关计算机技术,基于ERP的商务智能系统应用-计算机技术专业论文.docx
  3. 墨迹天气携手友盟+U-APM,共同打造良好应用性能体验
  4. android ios打包工具下载,IOS移动开发之快速打包工具---- iTunes 降级 到12.6,回到你熟悉的版本...
  5. 【Java工具类】(1)—Java中驼峰与下划线相互转换
  6. iOS播放与编辑HDR视频
  7. 三国志战略版S3开荒阵容搭配推荐
  8. 华为mate30epro和mate30pro的区别 购买哪个性价比高?
  9. 办理顺丰保价很有必要,这项服务真能帮上大忙
  10. 安卓小闹钟linux,Android--Alarm,定时闹钟