一、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才继续执行

简单示例


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

应用场景

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

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

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

public class CountDownLatchDemo2 {

    private static final ExecutorService threadPool = new ThreadPoolExecutor(50, 100,
5, TimeUnit.SECONDS,
new SynchronousQueue<>(),
new BasicThreadFactory.Builder().namingPattern("thread-%d").build()); public static void main(String[] args) { CountDownLatch countDownLatch = new CountDownLatch(2);
// 收集数据A
threadPool.execute(new TaskA(countDownLatch));
// 收集数据B
threadPool.execute(new TaskB(countDownLatch));
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 进行统计工作
System.out.println("进行统计工作");
// 向上汇报
System.out.println("向上汇报");
System.out.println("任务结束");
threadPool.shutdown();
} static class TaskA implements Runnable { private CountDownLatch countDownLatch; public TaskA(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
} @Override
public void run() { try {
System.out.println("执行任务A-----------");
TimeUnit.SECONDS.sleep(5);
System.out.println("执行任务A完成");
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} static class TaskB implements Runnable { private CountDownLatch countDownLatch; public TaskB(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
} @Override
public void run() { try {
System.out.println("执行任务B-----------");
TimeUnit.SECONDS.sleep(7);
System.out.println("执行任务B完成");
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }

运行结果

二、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() 释放一个许可,将其返回给信号量

简单示例


public class SemaphoreDemo { private static final ExecutorService threadPool = new ThreadPoolExecutor(20, 100,
1, TimeUnit.MINUTES,
new SynchronousQueue<>(),
new BasicThreadFactory.Builder().namingPattern("thread-%d").build()); private static volatile int count = 0; public static void main(String[] args) { Semaphore semaphore = new Semaphore(3); for (int i = 0; i < 100; i++) {
threadPool.execute(() -> {
try {
semaphore.acquire();
System.out.println("test--" + count);
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
} });
} } }

应用场景

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

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

public class SemaphoreDemo {

    private static final ExecutorService threadPool = new ThreadPoolExecutor(20, 100,
1, TimeUnit.MINUTES,
new SynchronousQueue<>(),
new BasicThreadFactory.Builder().namingPattern("thread-%d").build()); private static volatile int count = 0; public static void main(String[] args) { Semaphore semaphore = new Semaphore(3); for (int i = 0; i < 100; i++) {
threadPool.execute(() -> {
try { String id = new Random().nextInt() + "";
semaphore.acquire();
System.out.println("同事ID:" + id + ",开始体检");
try {
TimeUnit.SECONDS.sleep(3L);
TimeUnit.MILLISECONDS.sleep(new Random(10000).nextInt());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("同事ID:" + id + ",体检结束" + count);
count++;
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
} });
} } }

运行结果

三、CyclicBarrier

概念

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

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

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

简单示例

public class CyclicBarrierDemo {

    private static final ExecutorService threadPool = new ThreadPoolExecutor(50, 100,
1, TimeUnit.MINUTES,
new SynchronousQueue<>(),
new BasicThreadFactory.Builder().namingPattern("thread-%d").build()); public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(10);
for (int i = 0; i < 10; i++) {
threadPool.execute(() -> {
System.out.println("线程" + Thread.currentThread().getId() + "跑到100米,遇到栅栏,停下");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("继续跑完剩下300米");
});
} threadPool.shutdown(); } }

应用场景

还用上面CountDownLatch的例子,

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

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

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


public class CyclicBarrierDemo2 { private static final ExecutorService threadPool = new ThreadPoolExecutor(50, 100,
5, TimeUnit.SECONDS,
new SynchronousQueue<>(),
new BasicThreadFactory.Builder().namingPattern("thread-%d").build()); private static volatile boolean flag = false; public static void main(String[] args) { CyclicBarrier cb = new CyclicBarrier(2);
// 收集数据A
threadPool.execute(new TaskA(cb));
// 收集数据B
threadPool.execute(new TaskB(cb));
threadPool.shutdown();
} static class TaskA implements Runnable { private CyclicBarrier cb; public TaskA(CyclicBarrier cb) {
this.cb = cb;
} @Override
public void run() { try {
System.out.println("执行任务A-----------");
TimeUnit.SECONDS.sleep(5);
System.out.println("执行任务A完成");
cb.await();
if(!flag){
flag = true;
System.out.println("进行统计工作");
System.out.println("向上汇报");
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
} static class TaskB implements Runnable { private CyclicBarrier cb; public TaskB(CyclicBarrier cb) {
this.cb = cb;
} @Override
public void run() { try {
System.out.println("执行任务B-----------");
TimeUnit.SECONDS.sleep(7);
System.out.println("执行任务B完成");
cb.await();
if(!flag){
flag = true;
System.out.println("进行统计工作");
System.out.println("向上汇报");
System.out.println("任务结束");
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
} }

运行结果

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. jQuery 基础知识

    一.序言 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后的又一个优秀的JavaScript代码库(JavaScript框架).jQuery设计的宗旨是"W ...

  2. hystrix配置

    一.hystrix在生产中的建议 1.保持timeout的默认值(1000ms),除非需要修改(其实通常会修改) 2.保持threadpool的的线程数为10个,除非需要更多 3.依赖标准的报警和监控 ...

  3. 如果只有1小时学Python,看这篇就够了

    大家好,我是大鹏,城市数据团联合发起人,致力于Python数据分析.数据可视化的应用与教学. 和很多同学接触过程中,我发现自学Python数据分析的一个难点是资料繁多,过于复杂.大部分网上的资料总是从 ...

  4. vue-cli项目开发运行时内存暴涨卡死电脑

    最近开发一个vue项目时遇到电脑卡死问题,突然间系统就非常卡,然后卡着卡着就死机了,鼠标也动不了了,只能冷启动.而且因为是突然卡死,没来得及打开任务管理器. 最开始以为是硬盘的问题,但是在卡死几次后, ...

  5. PowerMockito单元测试中的Invalid use of argument matchers问题详解

    首先,简单说说PowerMockito进行单元测试的三部曲: 打桩,即为非测试目标方法设置返回值,这些返回值在测试目标方法中被使用.执行测试,调用测试目标方法.验证测试结果,如测试方法是否被执行,测试 ...

  6. Robot Framework--Scalar变量

    一.变量赋值 1)Set赋值 通常使用Set Variable关键字对变量进行赋值,其他Set相关的带Variable的关键字也可以进行赋值 赋值的时候,变量后面写不写『=』都可以,如下: 如果${v ...

  7. Mac+appium+iOS 环境搭建

    Mac+appium+iOS 环境搭建,需要用到的信息如下,参考搭建环境. 1.安装brew,安装介绍:https://jingyan.baidu.com/article/fec7a1e5ec3034 ...

  8. CSP模拟赛 Repulsed(树形DP)

    题面 ⼩ w ⼼⾥的⽕焰就要被熄灭了. 简便起⻅,假设⼩ w 的内⼼是⼀棵 n − 1 条边,n 个节点的树. 现在你要在每个节点⾥放⼀些个灭⽕器,每个节点可以放任意多个. 接下来每个节点都要被分配给 ...

  9. BZOJ4802 欧拉函数 (Pollard-Rho Miller-Robin)

    题目 求大数的欧拉函数φ\varphiφ 题解 Pollard-Rho 板子 CODE #pragma GCC optimize (3) #include <bits/stdc++.h> ...

  10. Codeforces Round #597 (Div. 2) B. Restricted RPS

    链接: https://codeforces.com/contest/1245/problem/B 题意: Let n be a positive integer. Let a,b,c be nonn ...