信号量同步是指在不同线程之间,通过传递同步信号量来协调线程执行的先后次序。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();
}
}

  注意:CountDownLatchawait方法建议使用带超时间的。不使用带超时时间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的更多相关文章

  1. Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo

    Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...

  2. Java多线程_同步工具CountDownLatch

    概念:CountDownLatch是多线程里面一个类似于计数器的高级同步工具,它的初始值代表线程的数量,当一个线程完成了任务后,CountDownLatch的值就减1,当值为0的时候,代表所有线程完成 ...

  3. Java多线程并发工具类-信号量Semaphore对象讲解

    Java多线程并发工具类-Semaphore对象讲解 通过前面的学习,我们已经知道了Java多线程并发场景中使用比较多的两个工具类:做加法的CycliBarrier对象以及做减法的CountDownL ...

  4. Java多线程的同步控制记录

    Java多线程的同步控制记录 一.重入锁 重入锁完全可以代替 synchronized 关键字.在JDK 1.5 早期版本,重入锁的性能优于 synchronized.JDK 1.6 开始,对于 sy ...

  5. Java多线程之同步集合和并发集合

    Java多线程之同步集合和并发集合 不管是同步集合还是并发集合他们都支持线程安全,他们之间主要的区别体现在性能和可扩展性,还有他们如何实现的线程安全. 同步集合类 Hashtable Vector 同 ...

  6. Java多线程编程(同步、死锁、生产消费者问题)

    Java多线程编程(同步.死锁.生产消费): 关于线程同步以及死锁问题: 线程同步概念:是指若干个线程对象并行进行资源的访问时实现的资源处理保护操作: 线程死锁概念:是指两个线程都在等待对方先完成,造 ...

  7. Java中多线程同步类 CountDownLatch

    在多线程开发中,常常遇到希望一组线程完成之后在执行之后的操作,java提供了一个多线程同步辅助类,可以完成此类需求: 类中常见的方法: 其中构造方法:CountDownLatch(int count) ...

  8. Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例

    概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 ...

  9. Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger

    在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...

随机推荐

  1. POJ-3821-Dining (拆点网络流)

    这题为什么不能用 左边放食物,中间放牛,后面放水? 原因很简单,假设一头牛喜欢两个食物AB和两种水AB. 此时可以从一个食物A,走到牛A,再走到水A. 但是还可以有另一条路,从另一个食物B,走到该牛A ...

  2. JavaScript的发展史

    一.JavaScript发展历程 1. 诞生 ​ JavaScript因互联网而生,紧跟浏览器的发展而发展. ​ 1990年,欧洲核能研究所(CERN)科学家在互联网(Internet)基础上,发明了 ...

  3. let const var 比较说明

    现在先来做两道练习题 for(var i=0;i<10;i++){ var a='a' let b = 'b' } console.log(a) console.log(b) for(var i ...

  4. VS误删sln项目文件怎么办

    以项目名为Test为例 打开Test/Test目录下的 Test.vcxproj 文件,试着运行一下,退出后提示保存sln文件,选择一个目录即可.

  5. 重新理解业务里程碑----HHR计划----以太一堂第二课

    ---- 理解业务背后的逻辑,抓住创业重点. 第一课:开始学习 1,FA : financial advisor.财务顾问. 2,本节课的目的:抓住创业的重点. 3,预热思考题: (1) 如果把你的整 ...

  6. Java基础知识笔记第七章:内部类和异常类

    内部类 /* *Java支持在一个类中定义另一个类,这样的类称为内部类,而包含内部类的类称为内部类的外嵌类 */ 重要关系: /* *1.内部类的外嵌类在内部类中仍然有效,内部类的方法也可以外嵌类的方 ...

  7. springMVC的 Converter转换器 和 Formatter

    Converter转换器 spring的Converter是可以将一种类型转换成另一种类型的一个对象, 自定义Converter需要实现Converter接口 日期转换器 import java.te ...

  8. linux 环境下安装jdk

    参考:https://blog.csdn.net/qq_30788949/article/details/81975954 安装 参考: https://www.cnblogs.com/shihaim ...

  9. Python基础-2 变量与常量

    变量与常量 变量:在程序运行过程中,值会发生变化的量 常量:在程序运行过程中,值不会发生变化的量 无论是变量还是常量,在创建时都会在内存中开辟一块空间,用于保存它的值. 这里有一点需要注意的是,在py ...

  10. A*算法和K短路(A*)

    堪称最好的A算法 https://blog.csdn.net/b2b160/article/details/4057781 K短路(A) https://www.jianshu.com/p/27019 ...