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() 方法 ...
随机推荐
- PyQt5操作SQLite数据库
1.操作SQLite数据库import sysfrom PyQt5.QtSql import QSqlDatabase,QSqlQueryfrom PyQt5.QtCore import * def ...
- Python中的lambda函数介绍
Lambda函数,即Lambda 表达式(lambda expression),是一个匿名函数(不存在函数名的函数),Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lam ...
- 【转】Swagger详解(SpringBoot+Swagger集成)
Swagger-API文档接口引擎Swagger是什么 Swagger是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器 ...
- 重新梳理IT知识之java-03循环
引用变量时要给变量赋值,如果循环进不去就会报错. 一.循环结构的四要素 1.初始化条件 2.循环条件 ---> 是Boolean类型 3.循环体 4.迭代条件 说明:通常情况下,循环结束都是因为 ...
- 重新梳理IT知识之java-02语法(二)
1.如何获取一个随机数 比如:10-99 调用方法:Math.random //Math.random方法得到的是double类型的值范围在[0.0,1.0),一般需要加工后才可满足开发要求. 代码: ...
- 临时解决执行 Composer Install 返回 Killed 的问题
昨天在 Linux 服务器上部署 PHP 项目时遇到了一个问题,系统为 Centos 7 ,1 核 1G 的配置.通过 Git 拉取代码后,由于是基于 Laravel 框架的项目,所以需要使用 Com ...
- 14.浏览器屏幕缩放bug修复
问题:浏览器缩放时,轮播图显示不全,滚动水平滚动条,发现图片缺失 解决:隐藏水平滚动条,页面都只提供垂直滚动条的需求 global.css /* 水平超出部分默认隐藏 */ #app { overfl ...
- 线上学习-语言模型 language model
chain rule markov assumption 评估语言模型 平滑方法
- dp-简单迷宫捡金币
链接:https://ac.nowcoder.com/acm/challenge/terminal 吃货LP参加了珠海美食节,每见一家摊位都会大吃一顿,但是如果不加收敛,接下来的日子就只能吃土了,所以 ...
- 数据库语言——SQL——基础部分——初篇
概述 SQL全称为Structured Query Language,是关系型数据库的语言标准,它并不与特定的数据库商品类型有关,例如Mysql,Oracle,DB2等等都可以使用SQL语言,它与特定 ...