信号量(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的更多相关文章

  1. Java并发编程之CAS

    CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术.简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替 ...

  2. Java并发编程之CAS第一篇-什么是CAS

    Java并发编程之CAS第一篇-什么是CAS 通过前面几篇的学习,我们对并发编程两个高频知识点了解了其中的一个—volatitl.从这一篇文章开始,我们将要学习另一个知识点—CAS.本篇是<凯哥 ...

  3. Java并发编程之CAS二源码追根溯源

    Java并发编程之CAS二源码追根溯源 在上一篇文章中,我们知道了什么是CAS以及CAS的执行流程,在本篇文章中,我们将跟着源码一步一步的查看CAS最底层实现原理. 本篇是<凯哥(凯哥Java: ...

  4. Java并发编程之CAS第三篇-CAS的缺点及解决办法

    Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...

  5. Java并发编程之set集合的线程安全类你知道吗

    Java并发编程之-set集合的线程安全类 Java中set集合怎么保证线程安全,这种方式你知道吗? 在Java中set集合是 本篇是<凯哥(凯哥Java:kagejava)并发编程学习> ...

  6. Java并发编程之AQS

    一.什么是AQS AQS(AbstractQueuedSynchronize:队列同步器)是用来构建锁或者其他同步组件的基础框架,很多同步类都是在它的基础上实现的,比如常用的ReentrantLock ...

  7. Java并发编程之Lock

    重入锁ReentrantLock 可以代替synchronized, 但synchronized更灵活. 但是, 必须必须必须要手动释放锁. try { lock.lock(); } finally ...

  8. Java并发编程之synchronized关键字

    整理一下synchronized关键字相关的知识点. 在多线程并发编程中synchronized扮演着相当重要的角色,synchronized关键字是用来控制线程同步的,可以保证在同一个时刻,只有一个 ...

  9. Java 并发编程之 Condition 接口

    本文部分摘自<Java 并发编程的艺术> 概述 任意一个 Java 对象,都拥有一个监视器方法,主要包括 wait().wait(long timeout).notify() 以及 not ...

随机推荐

  1. cookie和session的用法用途,执行流程,区别联系

    1.为什么要有cookie/session?在客户端浏览器向服务器发送请求,服务器做出响应之后,二者便会断开连接(一次会话结束).那么下次用户再来请求服务器,服务器没有任何办法去识别此用户是谁.比如w ...

  2. vs code 格式化 美化 html js css 插件 Beautify

    安装 Beautify 插件 然后 F1 输入 Beautify file 回车即可

  3. 模态对话框与非模态对话框(modeless)

    对话框有两种创建方式:DoModal和Creat. 其中DoModal创建的是模态的对话框,而Creat创建的是非模态的对话框下面总结下他们的不同. 对于模态的对话框,在该对话框被关闭前,用户将不能在 ...

  4. MySQL与MyBatis中的查询记录

    1.时间段查询 MySQL:select * from table where ctime >= CURDATE() and ctime <DATE_SUB(CURDATE(),INTER ...

  5. String 工具类

    package com.mytripod.util; import sun.rmi.runtime.Log; import java.io.UnsupportedEncodingException; ...

  6. linux netstat-查看Linux中网络系统状态信息

    博主推荐:更多网络测试相关命令关注 网络测试  收藏linux命令大全 netstat命令用来打印Linux中网络系统的状态信息,可让你得知整个Linux系统的网络情况. 语法 netstat(选项) ...

  7. ubuntu lamnp 环境的安装/卸载 及 配置

    安装mysql--------------------------------------sudo apt install mysql-server   #5.7版本 安装php----------- ...

  8. django-3 admin开启后台配置并展示表内容

    设置了superuser 之后,可以在run server 后, 通过浏览器访问后台,进行界面配置. 1. python manage.py creatersuperuser 此命令在manage.p ...

  9. Auto-Encoders实战

    目录 Outline Auto-Encoder 创建编解码器 训练 Outline Auto-Encoder Variational Auto-Encoders Auto-Encoder 创建编解码器 ...

  10. python3爬虫-爬取58同城上所有城市的租房信息

    from fake_useragent import UserAgent from lxml import etree import requests, os import time, re, dat ...