Java多线程信号量同步类CountDownLatch与Semaphore
信号量同步是指在不同线程之间,通过传递同步信号量来协调线程执行的先后次序。CountDownLatch是基于时间维度的Semaphore则是基于信号维度的。
1:基于执行时间的同步类CountDownLatch
例如现有3台服务器,需编写一个获取各个服务器状态的接口,准备开三个子线程每个线程获取一台服务器状态后统一返回三台服务器状态。主线程内定义计数器为3的CountDownLatch实例,各个子线程添加CountDownLatch实例引用,子线程执行完后对CountDownLatch进行countDown。主线程调用CountDownLatch实例的await方法等待所有子线程执行完后返回结果。不考虑异常情况的代码示例如下。
public class Main {
public static void main(String[] args) throws InterruptedException {
CountDownLatch count = new CountDownLatch(3);
Thread getServer1Status = new GetDataStatusThread("服务器1", count);
Thread getServer2Status = new GetDataStatusThread("服务器2", count);
Thread getServer3Status = new GetDataStatusThread("服务器3", count);
getServer1Status.start();
getServer2Status.start();
getServer3Status.start();
//await 使当前线程等待直至CountDownLatch的计数为0,除非线程中断
//count.await();
//await(long timeout, TimeUnit unit) 使当前线程等待直至CountDownLatch的计数为0,除非线程中断或经过指定的等候时间
count.await(10,TimeUnit.SECONDS);
System.out.println("所有服务器状态获取完成");
}
}
class GetDataStatusThread extends Thread {
private final CountDownLatch count;
public GetDataStatusThread(String threadName, CountDownLatch count) {
this.setName(threadName);
this.count = count;
}
@Override
public void run() {
System.out.println("获取" + this.getName() + "状态成功");
//递减CountDownLatch的计数,如果计数达到零,则释放所有等待的线程
count.countDown();
}
}
注意:CountDownLatch的await方法建议使用带超时间的。不使用带超时时间await的线程若计数器初始值设置的值达不到countDown(递减计数器计数)次数则该线程会一直等待至计数为0,除非线程中断
(例如子线程执行过程中出现异常执行不到countDown方法,顺便补充若子线程会抛出异常且该异常没有被主线程捕获到可通过线程方法setUncaughtExceptionHandler()捕获)。
2:基于空闲信号的同步类Semaphore
Semaphore可看作一个管理“许可证”的池,创建Semaphore实例时指定许可证数量,所有包含Semaphore实例引用的线程运行时通过acquire方法获取许可证,运行完成后通过release方法释放许可证。获取不到许可证等线程直到获取到空闲许可证才会执行。如下代码所示:某景区只有两个买票窗口(许可池大小)所有游客排队进行买票,准备买票的游客通过acquire占据当前窗口买票完成准备离开通过release方法表示当前窗口已空闲。
public class Window {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(2);
for (int i = 1; i <= 6; i++) {
new ByTicketThread("客户" + i, semaphore).start();
}
}
}
class ByTicketThread extends Thread {
private final Semaphore semaphore;
public ByTicketThread(String threadName, Semaphore semaphore) {
this.setName(threadName);
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire();
System.out.println(this.getName() + "正在买票。");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
System.out.println(this.getName() + "买票完成。");
}
}
}
Java多线程信号量同步类CountDownLatch与Semaphore的更多相关文章
- Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo
Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...
- Java多线程_同步工具CountDownLatch
概念:CountDownLatch是多线程里面一个类似于计数器的高级同步工具,它的初始值代表线程的数量,当一个线程完成了任务后,CountDownLatch的值就减1,当值为0的时候,代表所有线程完成 ...
- Java多线程并发工具类-信号量Semaphore对象讲解
Java多线程并发工具类-Semaphore对象讲解 通过前面的学习,我们已经知道了Java多线程并发场景中使用比较多的两个工具类:做加法的CycliBarrier对象以及做减法的CountDownL ...
- Java多线程的同步控制记录
Java多线程的同步控制记录 一.重入锁 重入锁完全可以代替 synchronized 关键字.在JDK 1.5 早期版本,重入锁的性能优于 synchronized.JDK 1.6 开始,对于 sy ...
- Java多线程之同步集合和并发集合
Java多线程之同步集合和并发集合 不管是同步集合还是并发集合他们都支持线程安全,他们之间主要的区别体现在性能和可扩展性,还有他们如何实现的线程安全. 同步集合类 Hashtable Vector 同 ...
- Java多线程编程(同步、死锁、生产消费者问题)
Java多线程编程(同步.死锁.生产消费): 关于线程同步以及死锁问题: 线程同步概念:是指若干个线程对象并行进行资源的访问时实现的资源处理保护操作: 线程死锁概念:是指两个线程都在等待对方先完成,造 ...
- Java中多线程同步类 CountDownLatch
在多线程开发中,常常遇到希望一组线程完成之后在执行之后的操作,java提供了一个多线程同步辅助类,可以完成此类需求: 类中常见的方法: 其中构造方法:CountDownLatch(int count) ...
- Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例
概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 ...
- Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger
在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...
随机推荐
- QLabel设置伙伴关系和快捷键(Alt+首字母)
Qlabe中设置伙伴关系是使用Setbuddy函数: Qlabel.Setbuddy(QLineEdit) #将Qlabel和QLineEdit之间设置伙伴关系 另外,需要配合热键(快捷键)进行使用, ...
- 13. 为什么我们会需要 Pod?
13. 为什么我们会需要 Pod? 13.1 docker容器的本质 """ docker容器的本质 是进程. 主要通过 Namespace 做隔离,Cgroups 做限 ...
- 路由器安全-FPM
1.FPM(也叫NGACL) FPM是Cisco IOS新一代的ACL,叫做Flexible Packet Matching,灵活的包匹配. 根据任意条件,无状态的匹配数据包的头部,负载,或者全部. ...
- 【剑指Offer面试编程题】题目1509:树中两个结点的最低公共祖先--九度OJ
题目描述: 给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数 ...
- FileUpload之FileItem类的常用方法
http://blog.csdn.net/chinaliuyan/article/details/7002014
- pyputer安装使用
pip install jupyter 请在终端(Mac / Linux)或命令提示符(Windows)上运行以下命令: jupyter notebook 登录地址在cmd安装运行完jupyter n ...
- idea代码神器:根据表生成代码
Easycode是idea的一个插件,可以直接对数据的表生成entity,controller,service,dao,mapper,无需任何编码,简单而强大. 1.安装(EasyCode) 我这里的 ...
- masonry使用添加紧凑、抗压属性
// 内容紧凑 - 优先完全显示内容,且不多占像素. [self.leftLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh for ...
- CSP2019 滚粗记
目录 CSP 2019 游记 DAY 0 DAY 1 DAY 2 CSP总结 自测之后 CSP 2019 游记 坐标:GD,GZ 人物:hyf 组别:J和S 任务:划水 目标:划水 任务奖励:退役证书 ...
- PAT A1103 Integer Factorization
线性dfs,注意每次深搜完状态的维护~ #include<bits/stdc++.h> using namespace std; ; vector<int> v,tmp,pat ...