Java并发编程系列之Semaphore详解
简单介绍
我们以饭店为例,假设饭店只有三个座位,一开始三个座位都是空的。这时如果同时来了三个客人,服务员人允许他们进去用餐,然后对外说暂无座位。后来的客人必须在门口等待,直到有客人离开。这时,如果有一个客人离开,服务员告诉客人,可以进来用餐,如果又有客人离开,则又可以进来客人用餐,如此往复。
在这个饭店中,座位是公共资源,每个人好比一个线程,服务员起的就是信号量的作用。信号量是一个非负整数,表示了当前公共资源的可用数目(在上面的例子中可以用空闲的座位类比信号量),当一个线程要使用公共资源时(在上面的例子中可以用客人比线程),首先要查看信号量,如果信号量的值大于1,则将其减1,然后去占有公共资源。如果信号量的值为0,则线程会将自己阻塞,直到有其它线程释放公共资源。
1、简单介绍Semaphore
a、可用来控制同时访问特定资源的线程数量,以此来达到协调线程工作。
b、维护了一个虚拟的资源池,如果许可为0则线程阻塞等待,直到许可大于0时又可以有机会获取许可了。
c、 内部也有公平锁、非公平锁来访问资源的静态内部类。
2、Semaphore方法
a、public Semaphore(int permits);// 创建一个给定许可数量的信号量对象,且默认以非公平锁方式获取资源
b、public Semaphore(int permits, boolean fair);//创建一个给定许可数量的信号量对象,且是否公平方式由传入的fair布尔参数值决定
c、public void acquire() ;//从此信号量获取一个许可,当许可数量小于零时,则阻塞等待
d、public void acquire(int permits) ;//从此信号量获取permits个许可,当许可数量小于零时,则阻塞等待,但是当阻塞等待的线程被唤醒后发现被中断过的话则会抛InterruptedException异常
e、public void acquireUninterruptibly(int permits) ;从此信号量获取permits个许可,当许可数量小于零时,则阻塞等待,但是当阻塞等待的线程被唤醒后发现被中断过的话则不会抛InterruptedException异常
f、public void release();//释放一个许可
g、public void release(int permits);释放permits个许可
以上只是列出主要方法名,方法详细解释,Semaphore类上面都有注释。就不一一累出来了。
举一个简单例子,帮助我们加深印象
/**
 * @author shuliangzhao
 * @Title: SemaPhoreTest
 * @ProjectName design-parent
 * @Description: TODO
 * @date 2019/6/5 22:50
 */
public class SemaPhoreTest {
    private Semaphore semaphore = new Semaphore(3);
    class TaskThread implements Runnable{
        private int id;
        public TaskThread(int id) {
            this.id = id;
        }
        @Override
        public void run() {
            try {
                semaphore.acquire();
                System.out.println("Thread " + id + " is working");
                Thread.sleep(2000);
                semaphore.release();
                System.out.println("Thread " + id + " is over");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        SemaPhoreTest semaPhoreTest = new SemaPhoreTest();
        /*for (int i = 0;i<6;i++) {
            Thread thread = new Thread(semaPhoreTest.new TaskThread(i));
            thread.start();
        }*/
        ExecutorService executorService = Executors.newCachedThreadPool();//同步队列线程
        executorService.submit(semaPhoreTest.new TaskThread(1));
        executorService.submit(semaPhoreTest.new TaskThread(2));
        executorService.submit(semaPhoreTest.new TaskThread(3));
        executorService.submit(semaPhoreTest.new TaskThread(4));
        executorService.submit(semaPhoreTest.new TaskThread(5));
        executorService.submit(semaPhoreTest.new TaskThread(6));
        executorService.submit(semaPhoreTest.new TaskThread(7));
        executorService.shutdown();
    }
}
运行结果

Java并发编程系列之Semaphore详解的更多相关文章
- Java并发编程系列之CyclicBarrier详解
		简介 jdk原文 A synchronization aid that allows a set of threads to all wait for each other to reach a co ... 
- Java并发编程1--synchronized关键字用法详解
		1.synchronized的作用 首先synchronized可以修饰方法或代码块,可以保证同一时刻只有一个线程可以执行这个方法或代码块,从而达到同步的效果,同时可以保证共享变量的内存可见性 2.s ... 
- java并发编程系列原理篇--JDK中的通信工具类Semaphore
		前言 java多线程之间进行通信时,JDK主要提供了以下几种通信工具类.主要有Semaphore.CountDownLatch.CyclicBarrier.exchanger.Phaser这几个通讯类 ... 
- Java并发编程系列-(2) 线程的并发工具类
		2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ... 
- Java并发编程系列-(4) 显式锁与AQS
		4 显示锁和AQS 4.1 Lock接口 核心方法 Java在java.util.concurrent.locks包中提供了一系列的显示锁类,其中最基础的就是Lock接口,该接口提供了几个常见的锁相关 ... 
- Java并发编程系列-(8) JMM和底层实现原理
		8. JMM和底层实现原理 8.1 线程间的通信与同步 线程之间的通信 线程的通信是指线程之间以何种机制来交换信息.在编程中,线程之间的通信机制有两种,共享内存和消息传递. 在共享内存的并发模型里,线 ... 
- 【原创】Java并发编程系列1:大纲
		[原创]Java并发编程系列1:大纲 一个人能力当中所蕴藏的潜能,远超过自己想象以外. 为什么要学习并发编程 随着现今互联网行业的迅猛发展,其业务复杂度.并发量也在不断增加,对程序的要求变得越来越高, ... 
- 干货:Java并发编程系列之volatile(二)
		接上一篇<Java并发编程系列之synchronized(一)>,这是第二篇,说的是关于并发编程的volatile元素. Java语言规范第三版中对volatile的定义如下:Java编程 ... 
- Java并发编程系列-(5) Java并发容器
		5 并发容器 5.1 Hashtable.HashMap.TreeMap.HashSet.LinkedHashMap 在介绍并发容器之前,先分析下普通的容器,以及相应的实现,方便后续的对比. Hash ... 
随机推荐
- FileWriter实现从一个文件中读取内容并写到另一个文件中
			FileWriter和FileOutputStream都是向文件写内容,区别是前台一次写一个字符,后者一次写一个字节 package com.janson.day20180827; import ja ... 
- 用Python实现阿里钉钉机器人读取数据库内容自动发群通知
			最近想把一些预警数据信息按照一定的要求自动发送到移动端APP,最终把目标放在了腾讯的微信和阿里的钉钉软件上,由于刚开始学习python,于是编程工具想用python来实现.微信使用群体最广,通过一天的 ... 
- python正则表达式提取字符串
			用python正则表达式提取字符串 在日常工作中经常遇见在文本中提取特定位置字符串的需求.python的正则性能好,很适合做这类字符串的提取,这里讲一下提取的技巧,正则表达式的基础知识就不说了,有兴趣 ... 
- 为什么要有uboot?带你全面分析嵌入式linux系统启动过程中uboot的作用
			1.为什么要有uboot 1.1.计算机系统的主要部件 (1)计算机系统就是以CPU为核心来运行的系统.典型的计算机系统有:PC机(台式机+笔记本).嵌入式设备(手机.平板电脑.游戏机).单片机(家用 ... 
- html to canvas
			html to canvas Screenshots https://html2canvas.hertzen.com/ https://github.com/niklasvh/html2canvas ... 
- noip模拟赛 业务办理
			[问题描述]在银行柜台前,有 n 个顾客排队办理业务. 队伍中从前往后,第 i 位顾客办理业务需要ti 分钟时间. 一位顾客的等待时间定义为:队伍中在他之前的所有顾客和他自己的办理业务时间的总和.第 ... 
- Win32编程API  基础篇 -- 4.消息循环
			消息循环 理解消息循环 为了编写任何即使是最简单的程序,了解windows程序的消息循环和整个消息发送结构是非常有必要的.既然我们已经尝试了一点消息处理的东西,我们应该对整个程序有更深入的理解,如果你 ... 
- ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01653: 表 SYS.AUD$ 无法通过 8192 (在表空间 SYSTEM 中) 扩展
			https://blog.csdn.net/zhangyong329/article/details/53421951 
- 母函数(Generating function)详解
			母函数(Generating function)详解 在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息.使用 ... 
- MVC和MVVM的区别
			现在是市面上使用MVVM模型越来越多,相关的前端框架的选择也相应增多. 那么什么是MVVM模型,它和传统MVC模型有什么区别,接下来我们来总结探讨一下. MVVM即Model-View-ViewMod ... 
