一、CountDownLatch

文档描述

A synchronization aid that allows one or more threads to wait until* a set of operations being performed in other threads completes.

是一个同步帮助工具,允许一个或多个线程等待一系列其他线程操作完后,再执行。

count down 倒计时

latch 插锁

在Java中Latch结尾的也叫 闭锁

用法

方法名 作用
await() 线程会被挂起,它会等待直到count值为0才继续执行

简单示例


  1. public class CountDownLatchDemo {
  2. private static final ExecutorService threadPool = new ThreadPoolExecutor(50, 100,
  3. 5, TimeUnit.SECONDS,
  4. new SynchronousQueue<>(),
  5. new BasicThreadFactory.Builder().namingPattern("thread-%d").build());
  6. public static void main(String[] args) throws InterruptedException {
  7. CountDownLatch countDownLatch = new CountDownLatch(10);
  8. for (int i = 1; i <= 10; i++) {
  9. threadPool.execute(() -> {
  10. System.out.println("test-"+new Random().nextInt());
  11. countDownLatch.countDown();
  12. });
  13. }
  14. countDownLatch.await();
  15. System.out.println("end");
  16. threadPool.shutdown();
  17. }
  18. }

应用场景

同事A需要执行任务A,进行A类数据的收集

同事B需要执行任务B,进行B类数据的收集

项目经理需要等到A和B的数据都收集齐之后,进行统计,然后向上汇报。

  1. public class CountDownLatchDemo2 {
  2. private static final ExecutorService threadPool = new ThreadPoolExecutor(50, 100,
  3. 5, TimeUnit.SECONDS,
  4. new SynchronousQueue<>(),
  5. new BasicThreadFactory.Builder().namingPattern("thread-%d").build());
  6. public static void main(String[] args) {
  7. CountDownLatch countDownLatch = new CountDownLatch(2);
  8. // 收集数据A
  9. threadPool.execute(new TaskA(countDownLatch));
  10. // 收集数据B
  11. threadPool.execute(new TaskB(countDownLatch));
  12. try {
  13. countDownLatch.await();
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17. // 进行统计工作
  18. System.out.println("进行统计工作");
  19. // 向上汇报
  20. System.out.println("向上汇报");
  21. System.out.println("任务结束");
  22. threadPool.shutdown();
  23. }
  24. static class TaskA implements Runnable {
  25. private CountDownLatch countDownLatch;
  26. public TaskA(CountDownLatch countDownLatch) {
  27. this.countDownLatch = countDownLatch;
  28. }
  29. @Override
  30. public void run() {
  31. try {
  32. System.out.println("执行任务A-----------");
  33. TimeUnit.SECONDS.sleep(5);
  34. System.out.println("执行任务A完成");
  35. countDownLatch.countDown();
  36. } catch (InterruptedException e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. }
  41. static class TaskB implements Runnable {
  42. private CountDownLatch countDownLatch;
  43. public TaskB(CountDownLatch countDownLatch) {
  44. this.countDownLatch = countDownLatch;
  45. }
  46. @Override
  47. public void run() {
  48. try {
  49. System.out.println("执行任务B-----------");
  50. TimeUnit.SECONDS.sleep(7);
  51. System.out.println("执行任务B完成");
  52. countDownLatch.countDown();
  53. } catch (InterruptedException e) {
  54. e.printStackTrace();
  55. }
  56. }
  57. }
  58. }

运行结果

二、Semaphore

文档描述

A counting semaphore.  Conceptually, a semaphore maintains a set of* permits.  Each {@link #acquire} blocks if necessary until a permit is* available, and then takes it.  Each {@link #release} adds a permit,* potentially releasing a blocking acquirer.* However, no actual permit objects are used; the {@code Semaphore} just* keeps a count of the number available and acts accordingly.**

Semaphores are often used to restrict the number of threads than can* access some (physical or logical) resource. For example, here is* a class that uses a semaphore to control access to a pool of items:

用于控制并发量。

用法

方法名 作用
acquire() 从该信号量获取一个许可,在获取许可前线程将一直阻塞
release() 释放一个许可,将其返回给信号量

简单示例


  1. public class SemaphoreDemo {
  2. private static final ExecutorService threadPool = new ThreadPoolExecutor(20, 100,
  3. 1, TimeUnit.MINUTES,
  4. new SynchronousQueue<>(),
  5. new BasicThreadFactory.Builder().namingPattern("thread-%d").build());
  6. private static volatile int count = 0;
  7. public static void main(String[] args) {
  8. Semaphore semaphore = new Semaphore(3);
  9. for (int i = 0; i < 100; i++) {
  10. threadPool.execute(() -> {
  11. try {
  12. semaphore.acquire();
  13. System.out.println("test--" + count);
  14. try {
  15. TimeUnit.SECONDS.sleep(3);
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. count++;
  20. semaphore.release();
  21. } catch (InterruptedException e) {
  22. e.printStackTrace();
  23. }
  24. });
  25. }
  26. }
  27. }

应用场景

公司有100个人需要体检,医院每次最多只能体检3人。

当有3个人在体检时,其他人只能等待,有1个人体检完,下一个人可以补上。

  1. public class SemaphoreDemo {
  2. private static final ExecutorService threadPool = new ThreadPoolExecutor(20, 100,
  3. 1, TimeUnit.MINUTES,
  4. new SynchronousQueue<>(),
  5. new BasicThreadFactory.Builder().namingPattern("thread-%d").build());
  6. private static volatile int count = 0;
  7. public static void main(String[] args) {
  8. Semaphore semaphore = new Semaphore(3);
  9. for (int i = 0; i < 100; i++) {
  10. threadPool.execute(() -> {
  11. try {
  12. String id = new Random().nextInt() + "";
  13. semaphore.acquire();
  14. System.out.println("同事ID:" + id + ",开始体检");
  15. try {
  16. TimeUnit.SECONDS.sleep(3L);
  17. TimeUnit.MILLISECONDS.sleep(new Random(10000).nextInt());
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. }
  21. System.out.println("同事ID:" + id + ",体检结束" + count);
  22. count++;
  23. semaphore.release();
  24. } catch (InterruptedException e) {
  25. e.printStackTrace();
  26. }
  27. });
  28. }
  29. }
  30. }

运行结果

三、CyclicBarrier

概念

和闭锁不同的是,栅栏是用来等待线程的,闭锁是用来等待时间。

当指定线程数都到达某个点,才开始执行后续的操作。

就好比有10个人赛跑,要跑400米,在100米设置一个栅栏,当这10个人都到达了这个栅栏的时候,才取消栅栏,全部放行。

简单示例

  1. public class CyclicBarrierDemo {
  2. private static final ExecutorService threadPool = new ThreadPoolExecutor(50, 100,
  3. 1, TimeUnit.MINUTES,
  4. new SynchronousQueue<>(),
  5. new BasicThreadFactory.Builder().namingPattern("thread-%d").build());
  6. public static void main(String[] args) {
  7. CyclicBarrier cyclicBarrier = new CyclicBarrier(10);
  8. for (int i = 0; i < 10; i++) {
  9. threadPool.execute(() -> {
  10. System.out.println("线程" + Thread.currentThread().getId() + "跑到100米,遇到栅栏,停下");
  11. try {
  12. cyclicBarrier.await();
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. } catch (BrokenBarrierException e) {
  16. e.printStackTrace();
  17. }
  18. System.out.println("继续跑完剩下300米");
  19. });
  20. }
  21. threadPool.shutdown();
  22. }
  23. }

应用场景

还用上面CountDownLatch的例子,

同事A需要执行任务A,进行A类数据的收集

同事B需要执行任务B,进行B类数据的收集

项目经理需要等到A和B的数据都收集齐之后,进行统计,然后向上汇报。


  1. public class CyclicBarrierDemo2 {
  2. private static final ExecutorService threadPool = new ThreadPoolExecutor(50, 100,
  3. 5, TimeUnit.SECONDS,
  4. new SynchronousQueue<>(),
  5. new BasicThreadFactory.Builder().namingPattern("thread-%d").build());
  6. private static volatile boolean flag = false;
  7. public static void main(String[] args) {
  8. CyclicBarrier cb = new CyclicBarrier(2);
  9. // 收集数据A
  10. threadPool.execute(new TaskA(cb));
  11. // 收集数据B
  12. threadPool.execute(new TaskB(cb));
  13. threadPool.shutdown();
  14. }
  15. static class TaskA implements Runnable {
  16. private CyclicBarrier cb;
  17. public TaskA(CyclicBarrier cb) {
  18. this.cb = cb;
  19. }
  20. @Override
  21. public void run() {
  22. try {
  23. System.out.println("执行任务A-----------");
  24. TimeUnit.SECONDS.sleep(5);
  25. System.out.println("执行任务A完成");
  26. cb.await();
  27. if(!flag){
  28. flag = true;
  29. System.out.println("进行统计工作");
  30. System.out.println("向上汇报");
  31. }
  32. } catch (InterruptedException e) {
  33. e.printStackTrace();
  34. } catch (BrokenBarrierException e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. }
  39. static class TaskB implements Runnable {
  40. private CyclicBarrier cb;
  41. public TaskB(CyclicBarrier cb) {
  42. this.cb = cb;
  43. }
  44. @Override
  45. public void run() {
  46. try {
  47. System.out.println("执行任务B-----------");
  48. TimeUnit.SECONDS.sleep(7);
  49. System.out.println("执行任务B完成");
  50. cb.await();
  51. if(!flag){
  52. flag = true;
  53. System.out.println("进行统计工作");
  54. System.out.println("向上汇报");
  55. System.out.println("任务结束");
  56. }
  57. } catch (InterruptedException e) {
  58. e.printStackTrace();
  59. } catch (BrokenBarrierException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. }
  64. }

运行结果

Java核心复习 —— J.U.C 并发工具类的更多相关文章

  1. Java核心复习——J.U.C AbstractQueuedSynchronizer

    第一眼看到AbstractQueuedSynchronizer,通常都会有这几个问题. AbstractQueuedSynchronizer为什么要搞这么一个类? 这个类是干什么的.有什么用? 这个类 ...

  2. Java核心复习——J.U.C LinkedBlockingQueue源码分析

    参考文档 LinkedBlockingQueue和ArrayBlockingQueue的异同

  3. Java核心复习——J.U.C ArrayBlockingQueue源码分析

    介绍 依赖关系 源码 构造方法 public ArrayBlockingQueue(int capacity) { this(capacity, false);//默认构造非公平的有界队列 } pub ...

  4. Java并发指南9:AQS共享模式与并发工具类的实现

    一行一行源码分析清楚 AbstractQueuedSynchronizer (三) 转自:https://javadoop.com/post/AbstractQueuedSynchronizer-3 ...

  5. Java并发编程-并发工具类及线程池

    JUC中提供了几个比较常用的并发工具类,比如CountDownLatch.CyclicBarrier.Semaphore. CountDownLatch: countdownlatch是一个同步工具类 ...

  6. Java并发(十六):并发工具类——Exchanger

    Exchanger(交换者)是一个用于线程间协作的工具类.Exchanger用于进行线程间的数据交换.它提供一个同步点,在这个同步点两个线程可以交换彼此的数据.这两个线程通过exchange方法交换数 ...

  7. Java并发(十五):并发工具类——信号量Semaphore

    先做总结: 1.Semaphore是什么? Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源. 把它比作是控制流量的红绿灯,比如XX马路要 ...

  8. Java并发(十四):并发工具类——CountDownLatch

    先做总结: 1.CountDownLatch 是什么? CountDownLatch 允许一个或多个线程等待其他线程(不一定是线程,某个操作)完成之后再执行. CountDownLatch的构造函数接 ...

  9. Java并发(十三):并发工具类——同步屏障CyclicBarrier

    先做总结 1.CyclicBarrier 是什么? CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).它要做的事情是,让一组线程到达一个屏障(也可以叫同步点) ...

随机推荐

  1. OS X系统特有文件目录说明

    os x特有的目录 OS X系统中,除了标准的unix目录外,还增加了特有的目录. /Applications 应用程序目录,默认所有的GUI应用程序都安装在这里: /Library 系统的数据文件. ...

  2. C语言中参数的传递

    普通情况: 调用函数参数的传递,是采取入栈的方式,先上图一张: Fun是被调用的函数,而为了演示其参数传递的过程,特意多设了几个参数,其传递参数的汇编代码如下: 可以看出,汇编代码中将这9个参数的前5 ...

  3. el-table——可编辑、拖拽排序与校验的formTableDrag

    背景: 1.利用form进行校验输入: 2.利用sortable操作Dom替换表格数据顺序: 3.利用lodash实现数据深拷贝与参数替换等 一:最外层的数组校验 <template> & ...

  4. jmeter第一次使用

    创建线程组 依次创建后,在http请求页面填入接口地址,参数,头信息,点击运行,然后查看结果树

  5. linux跳板机开发之trap信号机应用

    场景1:公司新招聘了一个配置管理员,他的工作是负责将公司开发人员写的新代码依次分发到办公室测试环境.IDC测试环境和正式线上环境.因此公司需要开发一个程序,当配置管理员登录服务器,只能进入分发的管理界 ...

  6. 前端框架开始学习Vue(一)

    MVVM开发思想图(图片可能会被缩小,请右键另存查看,图片来源于网络)   定义基本Vue代码结构   1 v-text,v-cloak,v-html命令 默认 v-text没有闪烁问题,但是会覆盖元 ...

  7. SSM - SpringBoot - SpringCloud

    SSM框架 Spring + Spring MVC + MyBatis:标准MVC模式 继 SSH (Struts+Spring+Hibernate)之后,主流的 Java EE企业级 Web应用程序 ...

  8. ASP.NET 下配置请求大小、请求时间等参数

    在邮件发送系统或者其他一些传送文件的网站中,用户传送文件的大小是有限制的,因为这样不但可以节省服务器的空间,还可以提高传送文件的速度.下面介绍如何在Web.Config文件中配置限制上传文件大小与时间 ...

  9. 在 windows 上安装 git 2.22

    下载 by win 下载地址:https://git-scm.com/download/win 如下图.选择对应的版本下载: 安装 by win 1.双击下载好的git安装包.弹出提示框.如下图: 2 ...

  10. python中的_xx, __xx, __xx__

    一.从模块分析 ########  bb.py (一个用来导入的模块) ########## var = 0_var = 1__var = 2__var__ = 3 1. from module im ...