java并发编程之Semaphore
信号量(Semaphore)。有时被称为信号灯。是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们可以正确、合理的使用公共资源。
一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要。在许可可用前会堵塞每个 acquire(),然后再获取该许可。每个 release() 加入一个许可。从而可能释放一个正在堵塞的获取者。
可是。不使用实际的许可对象,Semaphore 仅仅对可用许可的号码进行计数,并採取对应的行动。拿到信号量的线程能够进入代码。否则就等待。通过acquire()和release()获取和释放訪问许可。
package com.lala.shop; import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit; public class SemaphoreDemo
{
/**
* 这里演示了一个样例:十个人一起上厕所
* 假设一次仅仅能一个人上厕所,则总共须要时间:1+2+3+4+5+6+7+8+9+10=55分钟
* 假设一次能10个人一起上厕所。则总共须要时间:10分钟
*/
static void demonstration(int num) throws Exception
{
String[] users = {"刘梅","夏东海","夏雪","刘星","夏雨","爷爷","姥姥","玛丽","胡一统","林宁"}; CountDownLatch cdl = new CountDownLatch(users.length); Integer[] times = {1,2,3,4,5,6,7,8,9,10};
List<Integer> timeList = Arrays.asList(times);
Collections.shuffle(timeList); Semaphore sph = new Semaphore(num); ExecutorService runner = Executors.newCachedThreadPool(); Instant start = Instant.now(); for(int i=0; i<users.length; i++)
{
final int index = i;
runner.submit(() -> {
try
{
//拿到信号灯,准备上厕所
sph.acquire(); long time = timeList.get(index); TimeUnit.SECONDS.sleep(time); System.out.println(users[index] + "如厕完成。共花费时间:" + time);
cdl.countDown();
//事情已经办完,释放信号灯
sph.release();
} catch (Exception e)
{
e.printStackTrace();
}
});
}
runner.shutdown(); cdl.await(); Instant end = Instant.now();
Duration speed = Duration.between(start, end);
long seconds = speed.getSeconds();//秒表示
System.out.println("所有上完厕所(一次仅仅能有" + num + "人如厕),总共花了时间:" + seconds);
}
public static void main(String[] args) throws Exception
{
demonstration(5);
}
}
假设调用方式为:
demonstration(5);
则,输出为:
夏雪如厕完成。共花费时间:1
夏雨如厕完成,共花费时间:3
刘星如厕完成,共花费时间:4
爷爷如厕完成,共花费时间:6
夏东海如厕完成,共花费时间:8
刘梅如厕完成,共花费时间:9
胡一统如厕完成。共花费时间:2
玛丽如厕完成,共花费时间:7
林宁如厕完成,共花费时间:5
姥姥如厕完成,共花费时间:10
所有上完厕所(一次仅仅能有5人如厕),总共花了时间:13
假设调用方式为:
demonstration(1);
则,输出为:
刘梅如厕完成,共花费时间:10
夏东海如厕完成,共花费时间:6
夏雪如厕完成,共花费时间:3
刘星如厕完成。共花费时间:9
夏雨如厕完成。共花费时间:8
爷爷如厕完成。共花费时间:4
姥姥如厕完成,共花费时间:1
玛丽如厕完成。共花费时间:5
胡一统如厕完成,共花费时间:7
林宁如厕完成,共花费时间:2
所有上完厕所(一次仅仅能有1人如厕),总共花了时间:55
假设调用方式为
demonstration(10); 则输出为:
夏雨如厕完成,共花费时间:1
夏东海如厕完成,共花费时间:2
爷爷如厕完成,共花费时间:3
刘星如厕完成。共花费时间:4
刘梅如厕完成,共花费时间:5
胡一统如厕完成。共花费时间:6
林宁如厕完成,共花费时间:7
姥姥如厕完成,共花费时间:8
玛丽如厕完成,共花费时间:9
夏雪如厕完成,共花费时间:10
所有上完厕所(一次仅仅能有10人如厕)。总共花了时间:10
java并发编程之Semaphore的更多相关文章
- Java并发编程之CAS
CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术.简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替 ...
- Java并发编程之CAS第一篇-什么是CAS
Java并发编程之CAS第一篇-什么是CAS 通过前面几篇的学习,我们对并发编程两个高频知识点了解了其中的一个—volatitl.从这一篇文章开始,我们将要学习另一个知识点—CAS.本篇是<凯哥 ...
- Java并发编程之CAS二源码追根溯源
Java并发编程之CAS二源码追根溯源 在上一篇文章中,我们知道了什么是CAS以及CAS的执行流程,在本篇文章中,我们将跟着源码一步一步的查看CAS最底层实现原理. 本篇是<凯哥(凯哥Java: ...
- Java并发编程之CAS第三篇-CAS的缺点及解决办法
Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...
- Java并发编程之set集合的线程安全类你知道吗
Java并发编程之-set集合的线程安全类 Java中set集合怎么保证线程安全,这种方式你知道吗? 在Java中set集合是 本篇是<凯哥(凯哥Java:kagejava)并发编程学习> ...
- Java并发编程之AQS
一.什么是AQS AQS(AbstractQueuedSynchronize:队列同步器)是用来构建锁或者其他同步组件的基础框架,很多同步类都是在它的基础上实现的,比如常用的ReentrantLock ...
- Java并发编程之Lock
重入锁ReentrantLock 可以代替synchronized, 但synchronized更灵活. 但是, 必须必须必须要手动释放锁. try { lock.lock(); } finally ...
- Java并发编程之synchronized关键字
整理一下synchronized关键字相关的知识点. 在多线程并发编程中synchronized扮演着相当重要的角色,synchronized关键字是用来控制线程同步的,可以保证在同一个时刻,只有一个 ...
- Java 并发编程之 Condition 接口
本文部分摘自<Java 并发编程的艺术> 概述 任意一个 Java 对象,都拥有一个监视器方法,主要包括 wait().wait(long timeout).notify() 以及 not ...
随机推荐
- CE工具里自带的学习工具--第五关
图解: 此时会弹出一个对话框,选择是就可以了,最终会看到:
- 为了安全请不要随意在页面中设置validateRequest="false"
为了安全请不要随意在页面中设置validateRequest="false" 分类: ASP.NET2009-04-12 17:24 531人阅读 评论(0) 收藏 举报 asp. ...
- JAVA基础——IO流字符流
字符流 字节流提供了处理任何类型输入/输出操作的功能(因为对于计算机而言,一切都是0和1,只需把数据以字节形式表示就够了),但它们不可以直接操作Unicode字符,因为上一篇文章写了,一个Unicod ...
- Oracle中如何插入特殊字符: &amp; 和 &#39; (多种解决方案)
Oracle中如何插入特殊字符:& 和 ' (多种解决方案)今天在导入一批数据到Oracle时,碰到了一个问题:Toad提示要给一个自定义变量AMP赋值,一开始我很纳闷,数据是一系列的Inse ...
- 诊断:RHEL7安装11.2RAC时root.sh错误ohasd failed to start
RHEL 7.5中安装11gRAC时,在grid infrastructure的root.sh执行时,报错: # /oracle/product/11g/grid/root.sh ... Adding ...
- 杀了个回马枪,还是说说position:sticky吧
<style> article { max-width: 600px; margin: 1em auto; } article h4, article footer { position: ...
- CodeForces - 1020C C - Elections(贪心+枚举)
题目: 党派竞争投票 有n个人,m个党派,这n个人每个人有一个想要投的党派的编号Pi,如果想要这个人改变他的想法,那么就需要花费Ci元钱. 现在你是编号为1的党派,如果你想要赢(你的票数严格大于其他党 ...
- <Redis> 入门六 主从复制方式的集群
1.集群如何操作 现在有三台虚拟机,ip分别为100,105,106,将100作为master,其他两台作为slave 1.vim redis.conf 以前的版本是 slaveof <mast ...
- 如何设置路由器的MTU
前几天搞了个ER-X,总觉得没有发挥其最大的能力.今天查了下如何设置MTU,罗列如下,备忘. 1. 目前都是PPPOE,这个不管网络如何复杂,均不要在路由后面计算封包大小.正确的是电脑直接连猫,直接拔 ...
- windows资源监控常用计数器解释
随笔有些是自己写的,有些是根据网上的东西自己整理的,文章基本都是别人的,只是为方便查看复制到那里