Java并发包下的几个API
并发包
(计数器)CountDownLatch
CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。
import java.util.concurrent.CountDownLatch;
public class CountDownlatchTest {
public static void main(String[] args) {
CountDownLatch count = new CountDownLatch(2);
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始执行-->" + System.currentTimeMillis());
count.countDown();
System.out.println(Thread.currentThread().getName() + "结束执行-->" + System.currentTimeMillis());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始执行-->" + System.currentTimeMillis());
count.countDown();
System.out.println(Thread.currentThread().getName() + "结束执行-->" + System.currentTimeMillis());
}
}).start();
try {
count.await(); // 当Count减为0 时,执行后面的代码
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("两个子线程执行完毕....");
System.out.println("主线程继续执行.....");
for (int i = 0; i < 10; i++) {
System.out.println("main,i:" + i);
}
}
}
执行结果
Thread-0开始执行-->1564281731639
Thread-0结束执行-->1564281731639
Thread-1开始执行-->1564281731639
Thread-1结束执行-->1564281731639
两个子线程执行完毕....
主线程继续执行.....
main,i:0
main,i:1
main,i:2
main,i:3
main,i:4
main,i:5
main,i:6
main,i:7
main,i:8
main,i:9
(屏障)CyclicBarrier
CyclicBarrier初始化时规定一个数目,然后计算调用了CyclicBarrier.await()进入等待的线程数。当线程数达到了这个数目时,所有进入等待状态的线程被唤醒并继续。
CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。
CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
for (int i = 0; i < 5; i++) {
Writer writer = new Writer(cyclicBarrier);
writer.start();
}
}
}
class Writer extends Thread {
private CyclicBarrier cyc;
public Writer(CyclicBarrier cyc) {
this.cyc = cyc;
}
@Override
public void run() {
System.out.println("线程" + Thread.currentThread().getName() + ",正在写入数据");
try {
Thread.sleep(3000);
} catch (Exception e) {
// TODO: handle exception
}
System.out.println("线程" + Thread.currentThread().getName() + ",写入数据成功.....");
try {
cyc.await();
} catch (Exception e) {
}
System.out.println("所有线程执行完毕..........");
}
}
执行结果
线程Thread-0,正在写入数据
线程Thread-2,正在写入数据
线程Thread-1,正在写入数据
线程Thread-3,正在写入数据
线程Thread-4,正在写入数据
线程Thread-3,写入数据成功.....
线程Thread-1,写入数据成功.....
线程Thread-0,写入数据成功.....
线程Thread-2,写入数据成功.....
线程Thread-4,写入数据成功.....
所有线程执行完毕..........
所有线程执行完毕..........
所有线程执行完毕..........
所有线程执行完毕..........
所有线程执行完毕..........
(计数信号量)Semaphore
Semaphore是一种基于计数的信号量。它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞。
Semaphore可以用来构建一些对象池,资源池之类的,比如数据库连接池,我们也可以创建计数为1的Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量,表示两种互斥状态。它的用法如下:
semp.availablePermits()//函数用来获取当前可用的资源数量
semp.acquire(); //申请资源
semp.release();// 释放资源
// 创建一个计数阈值为5的信号量对象
// 只能5个线程同时访问
Semaphore semp = new Semaphore(5);
try {
// 申请许可
semp.acquire();
try {
// 业务逻辑
}catch (Exception e){
} finally {
// 释放许可
semp.release();
}
}catch(InterruptedException e){ }
案例:
需求:
一个商店只有3个抓娃娃机,但是有10个人要来抓娃娃,那怎么办?假设10的人的编号分别为1-10,并且1号先到,10号最后到。那么1-3号来的时候必然有可用抓娃娃机,可以开始抓娃娃,4号来的时候需要看看前面3人是否有人抓完了,如果有人抓完,4号就开始抓娃娃,否则等待。同样的道理,4-10号也需要等待正在抓娃娃的人抓完才能抓,并且谁先开始抓娃娃要看等待的人是否有素质,是否能遵守先来先用抓玩玩机的规则。
代码:
import java.util.Random;
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
public static void main(String[] args) {
Semaphore semp = new Semaphore(3);
for (int i = 0; i <= 10; i++) {
CatchDollThread thread = new CatchDollThread("thread-" + i, semp);
thread.start();
}
}
}
class CatchDollThread extends Thread {
private String name;
private Semaphore cad;
public CatchDollThread(String name, Semaphore cad) {
this.name = name;
this.cad = cad;
}
@Override
public void run() {
int availablePermits = cad.availablePermits();
if (availablePermits > 0) {
System.out.println(this.name + "说: 有空闲的抓娃娃机");
} else {
System.out.println(this.name + "说: 没有空闲的娃娃机了");
}
try {
// 申请资源
cad.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.name + "开始抓娃娃" + ",此时空闲的机器:" + cad.availablePermits());
try {
Thread.sleep(new Random().nextInt(1000));
} catch (Exception e) {
}
System.out.println(this.name + "抓完娃娃");
// 释放资源
cad.release();
}
}
执行结果
thread-1说: 有空闲的抓娃娃机
thread-3说: 有空闲的抓娃娃机
thread-2说: 有空闲的抓娃娃机
thread-0说: 有空闲的抓娃娃机
thread-4说: 没有空闲的娃娃机了
thread-2开始抓娃娃,此时空闲的机器:0
thread-3开始抓娃娃,此时空闲的机器:1
thread-1开始抓娃娃,此时空闲的机器:2
thread-5说: 没有空闲的娃娃机了
thread-6说: 没有空闲的娃娃机了
thread-7说: 没有空闲的娃娃机了
thread-8说: 没有空闲的娃娃机了
thread-9说: 没有空闲的娃娃机了
thread-10说: 没有空闲的娃娃机了
thread-1抓完娃娃
thread-0开始抓娃娃,此时空闲的机器:0
thread-3抓完娃娃
thread-4开始抓娃娃,此时空闲的机器:0
thread-4抓完娃娃
thread-5开始抓娃娃,此时空闲的机器:0
thread-0抓完娃娃
thread-6开始抓娃娃,此时空闲的机器:0
thread-2抓完娃娃
thread-7开始抓娃娃,此时空闲的机器:0
thread-6抓完娃娃
thread-8开始抓娃娃,此时空闲的机器:0
thread-5抓完娃娃
thread-9开始抓娃娃,此时空闲的机器:0
thread-8抓完娃娃
thread-10开始抓娃娃,此时空闲的机器:0
thread-10抓完娃娃
thread-7抓完娃娃
thread-9抓完娃娃
Java并发包下的几个API的更多相关文章
- Java并发包下锁学习第一篇:介绍及学习安排
Java并发包下锁学习第一篇:介绍及学习安排 在Java并发编程中,实现锁的方式有两种,分别是:可以使用同步锁(synchronized关键字的锁),还有lock接口下的锁.从今天起,凯哥将带领大家一 ...
- Java并发包下锁学习第二篇Java并发基础框架-队列同步器介绍
Java并发包下锁学习第二篇队列同步器 还记得在第一篇文章中,讲到的locks包下的类结果图吗?如下图: 从图中,我们可以看到AbstractQueuedSynchronizer这个类很重要(在本 ...
- Java基础(下)(JVM、API)
Java基础(下) 第三部分:Java源程序的编辑 我们知道,计算机是不能直接理解源代码中的高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序. 翻译 ...
- java并发包下的并发工具类
1.Exchanger 功能:用于线程间数据的交换 应用场景:1)遗传算法,目前还不是特别理解 2)校对工作,假设A,B线程做同一件任务,可以通过数据校验判断两线程是否正确的工作 例子:是一个简单的 ...
- 死磕 java并发包之AtomicStampedReference源码分析(ABA问题详解)
问题 (1)什么是ABA? (2)ABA的危害? (3)ABA的解决方法? (4)AtomicStampedReference是什么? (5)AtomicStampedReference是怎么解决AB ...
- Java并发包——线程安全的Collection相关类
Java并发包——线程安全的Collection相关类 摘要:本文主要学习了Java并发包下线程安全的Collection相关的类. 部分内容来自以下博客: https://www.cnblogs.c ...
- Java并发包——Atomic操作
Java并发包——Atomic操作 摘要:本文主要学习了Java并发包下的atomic包中有关原子操作的一些类. 部分内容来自以下博客: https://blog.csdn.net/qq_303796 ...
- Java并发包——线程安全的Map相关类
Java并发包——线程安全的Map相关类 摘要:本文主要学习了Java并发包下线程安全的Map相关的类. 部分内容来自以下博客: https://blog.csdn.net/bill_xiang_/a ...
- paip.web数据绑定 下拉框的api设计 选择框 uapi python .net java swing jsf总结
paip.web数据绑定 下拉框的api设计 选择框 uapi python .net java swing jsf总结 ====总结: 数据绑定下拉框,Uapi 1.最好的是默认绑定..Map(k ...
随机推荐
- RocketMQ中Broker的刷盘源码分析
上一篇博客的最后简单提了下CommitLog的刷盘 [RocketMQ中Broker的消息存储源码分析] (这篇博客和上一篇有很大的联系) Broker的CommitLog刷盘会启动一个线程,不停地 ...
- 微信公众平台注册及AppID和AppSecret的获取
一.注册公众平台 1.入口 浏览器搜索“微信公众平台”,进入官网,点右上角立即注册. 2.选择账号类型 注册前需要选择一个账号类型,共有4个账号类型可以选择,每种类型能提供不同的功能,功能区别见下图. ...
- 聊聊目标管理之 OKR
这篇文章我们不谈技术,聊点轻松的,那聊什么呢?聊一下最近很火的目标管理 OKR.不知道小伙伴你们的公司什么情况,我的公司今年开始推行 OKR,用了大半年的时间,感觉效果还不错,上周六又参加了一天的复盘 ...
- Go中的反射reflect
前面我们在学习到struct结构体的时候,因为结构体中的字段首字母大写,而我们想把json文件映射到该结构体上时,需要在在结构体字段后面加上json标签,表明结构体字段和json字段的映射关系.这其中 ...
- 全球十大OTA 谁能有一席之地?
全球十大OTA 谁能有一席之地? http://www.traveldaily.cn/article/78381/1 2014-03-05 来源:i黑马 随着旅游行业日新月异的发展,在线旅游网站的出现 ...
- ES 26 - 通过partial update局部更新索引文档 (partial update增量修改原理)
目录 1 什么是partial update 1.1 全量修改文档的原理 1.2 修改指定field的思路 1.3 partial update的优势 1.4 partial update的使用 2 ...
- 压力测试-jmeter
1. 场景描述 新申请的服务器,要压测下python算法程序最多能执行多少条数据,有几年没用压力测试工具-jmeter了,重新下载了最新版本,记录下,也希望能帮到准备使用jmeter做压测的朋友. 2 ...
- MapReduce on Yarn运行原理
一.概念综述 MapReduce是一种可用于数据处理的编程模型(或计算模型),该模型可以比较简单,但想写出有用的程序却不太容易.MapReduce能将大型数据处理任务分解成很多单个的.可以在服务器集群 ...
- HTTP2.0的多路复用和HTTP1.X中的长连接复用区别
HTTP/2 多路复用 (Multiplexing) 多路复用允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息 HTTP1.1 在HTTP/1.1协议中,浏览器客户端在同一时间,针 ...
- Python模块之pexpect
一.pexpect模块介绍 Pexpect使Python成为控制其他应用程序的更好工具.可以理解为Linux下的expect的Python封装,通过pexpect我们可以实现对ssh,ftp,pass ...