信号量(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. window10换系统为windows7

    第一步 第二步 第三步 下载系统:http://www.dnxtc.net 1.GHO镜像安装器和WIN7,GHO文件必须一起放在除C盘外的其他盘的根目录 2.“GHO镜像安装器“工具上右键管理员方式 ...

  2. 第2节 hive基本操作:9、hive当中创建外部表的语法及外部表的操作&分区表的语法和操作

    外部表: 外部表说明: 外部表因为是指定其他的hdfs路径的数据加载到表当中来,所以hive表会认为自己不完全独占这份数据,所以删除hive表的时候,数据仍然存放在hdfs当中,不会删掉 管理表和外部 ...

  3. BZOJ3545 Peaks 离线处理+线段树合并

    题意: 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经 ...

  4. Centos6 安装nginx

    一.编译安装nginx 1.安装nginx所需要的库pcre,pcre的全称为:perl compatible regular expression即perl正则表达式,是为了使nginx具备URL重 ...

  5. socketserver模块使用方法

    一.socketserver模块介绍 Python提供了两个基本的socket模块.一个是socket,它提供了标准的BSD Socket API: 另一个是socketserver,它提供了服务器中 ...

  6. mysql-5.7.17-winx64免安装配置

    一,下载mysql-5.7.17-winx64.zip 地址:https://dev.mysql.com/downloads/file/?id=467269 二,解压到自己的某个磁盘:data文件夹和 ...

  7. input输入框的readonly属性-----http://www.w3school.com.cn/tags/tag_input.asp

    http://www.w3school.com.cn/tags/tag_input.asp input输入框的readonly属性 查询方法: 1.先找官方的文档,api 2.官方的有看不懂的再百度相 ...

  8. 【转】Java IO流 overview

    Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  9. hihoCoder#1119 小Hi小Ho的惊天大作战:扫雷·二

    原题地址 没有复杂算法,就是麻烦,写起来细节比较多,比较考验细心,一次AC好开心. 代码: #include <iostream> #include <vector> #inc ...

  10. 2018/2/14 x-pack的学习

    x-pack是什么?它能提供的作用如下,下面描述的这些功能都属于x-park:Shield: 提供对数据的 Password-Protect,以及加密通信.基于角色的权限控制,IP 过滤,审计,可以有 ...