Java核心复习 —— J.U.C 并发工具类
一、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 并发工具类的更多相关文章
- Java核心复习——J.U.C AbstractQueuedSynchronizer
第一眼看到AbstractQueuedSynchronizer,通常都会有这几个问题. AbstractQueuedSynchronizer为什么要搞这么一个类? 这个类是干什么的.有什么用? 这个类 ...
- Java核心复习——J.U.C LinkedBlockingQueue源码分析
参考文档 LinkedBlockingQueue和ArrayBlockingQueue的异同
- Java核心复习——J.U.C ArrayBlockingQueue源码分析
介绍 依赖关系 源码 构造方法 public ArrayBlockingQueue(int capacity) { this(capacity, false);//默认构造非公平的有界队列 } pub ...
- Java并发指南9:AQS共享模式与并发工具类的实现
一行一行源码分析清楚 AbstractQueuedSynchronizer (三) 转自:https://javadoop.com/post/AbstractQueuedSynchronizer-3 ...
- Java并发编程-并发工具类及线程池
JUC中提供了几个比较常用的并发工具类,比如CountDownLatch.CyclicBarrier.Semaphore. CountDownLatch: countdownlatch是一个同步工具类 ...
- Java并发(十六):并发工具类——Exchanger
Exchanger(交换者)是一个用于线程间协作的工具类.Exchanger用于进行线程间的数据交换.它提供一个同步点,在这个同步点两个线程可以交换彼此的数据.这两个线程通过exchange方法交换数 ...
- Java并发(十五):并发工具类——信号量Semaphore
先做总结: 1.Semaphore是什么? Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源. 把它比作是控制流量的红绿灯,比如XX马路要 ...
- Java并发(十四):并发工具类——CountDownLatch
先做总结: 1.CountDownLatch 是什么? CountDownLatch 允许一个或多个线程等待其他线程(不一定是线程,某个操作)完成之后再执行. CountDownLatch的构造函数接 ...
- Java并发(十三):并发工具类——同步屏障CyclicBarrier
先做总结 1.CyclicBarrier 是什么? CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).它要做的事情是,让一组线程到达一个屏障(也可以叫同步点) ...
随机推荐
- mysql建表常用命令
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RD ...
- HTML认识一
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- sql server 游标和with as使用
) --声明变量,需要读取的数据 DECLARE cur CURSOR --去掉STATIC关键字即可 FOR WITH Emp AS (SELECT acc.* FROM GXSpreadDB.db ...
- shell 函数的高级用法
函数介绍 linux shell中的函数和大多数编程语言中的函数一样 将相似的任务或者代码封装到函数中,供其他地方调用 语法格式 如何调用函数 shell终端中定义函数 [root@master da ...
- 解析CentOS 7中系统文件与目录管理
Linux目录结构 Linux目录结构是树形的目录结构 根目录 所有分区.目录.文件等的位置起点 整个树形目录结构中,使用独立的一个"/"表示 常见的子目录 目录 目录名称 目录 ...
- python词云图之WordCloud
1. 导入需要的包package import matplotlib.pyplot as plt from scipy.misc import imread from wordcloud import ...
- linux复制、压缩打包、解压缩等操作
1. 复制:cp命令,可复制一个文件夹下的所有文件和子目录.子文件,但是不包括本目录名,例如:不想包含目录名python3.7,想包含的是该目录下的所有子文件和子目录 cp -r /usr/local ...
- java相关网址汇总2
分享几个高质量的技术博客和网站. 一.博客 0.酷壳 - COOLSHELL 博客地址是 https://coolshell.cn/. 这个博客的作者是技术圈基本无人不知的技术大牛,江湖人称耗子叔,网 ...
- What is URL Encoding and How does it work?
Introduction A URL (Uniform Resource Locator) is the address of a resource in the world wide web. UR ...
- 大数据之路week07--day03(Hadoop深入理解,JAVA代码编写WordCount程序,以及扩展升级)
什么是MapReduce 你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃. MapReduce方法则是: 1.给在座的所有玩家中分配这摞牌 2.让每个玩家数自己手中的牌有几 ...