简单介绍

我们以饭店为例,假设饭店只有三个座位,一开始三个座位都是空的。这时如果同时来了三个客人,服务员人允许他们进去用餐,然后对外说暂无座位。后来的客人必须在门口等待,直到有客人离开。这时,如果有一个客人离开,服务员告诉客人,可以进来用餐,如果又有客人离开,则又可以进来客人用餐,如此往复。
在这个饭店中,座位是公共资源,每个人好比一个线程,服务员起的就是信号量的作用。信号量是一个非负整数,表示了当前公共资源的可用数目(在上面的例子中可以用空闲的座位类比信号量),当一个线程要使用公共资源时(在上面的例子中可以用客人比线程),首先要查看信号量,如果信号量的值大于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详解的更多相关文章

  1. Java并发编程系列之CyclicBarrier详解

    简介 jdk原文 A synchronization aid that allows a set of threads to all wait for each other to reach a co ...

  2. Java并发编程1--synchronized关键字用法详解

    1.synchronized的作用 首先synchronized可以修饰方法或代码块,可以保证同一时刻只有一个线程可以执行这个方法或代码块,从而达到同步的效果,同时可以保证共享变量的内存可见性 2.s ...

  3. java并发编程系列原理篇--JDK中的通信工具类Semaphore

    前言 java多线程之间进行通信时,JDK主要提供了以下几种通信工具类.主要有Semaphore.CountDownLatch.CyclicBarrier.exchanger.Phaser这几个通讯类 ...

  4. Java并发编程系列-(2) 线程的并发工具类

    2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...

  5. Java并发编程系列-(4) 显式锁与AQS

    4 显示锁和AQS 4.1 Lock接口 核心方法 Java在java.util.concurrent.locks包中提供了一系列的显示锁类,其中最基础的就是Lock接口,该接口提供了几个常见的锁相关 ...

  6. Java并发编程系列-(8) JMM和底层实现原理

    8. JMM和底层实现原理 8.1 线程间的通信与同步 线程之间的通信 线程的通信是指线程之间以何种机制来交换信息.在编程中,线程之间的通信机制有两种,共享内存和消息传递. 在共享内存的并发模型里,线 ...

  7. 【原创】Java并发编程系列1:大纲

    [原创]Java并发编程系列1:大纲 一个人能力当中所蕴藏的潜能,远超过自己想象以外. 为什么要学习并发编程 随着现今互联网行业的迅猛发展,其业务复杂度.并发量也在不断增加,对程序的要求变得越来越高, ...

  8. 干货:Java并发编程系列之volatile(二)

    接上一篇<Java并发编程系列之synchronized(一)>,这是第二篇,说的是关于并发编程的volatile元素. Java语言规范第三版中对volatile的定义如下:Java编程 ...

  9. Java并发编程系列-(5) Java并发容器

    5 并发容器 5.1 Hashtable.HashMap.TreeMap.HashSet.LinkedHashMap 在介绍并发容器之前,先分析下普通的容器,以及相应的实现,方便后续的对比. Hash ...

随机推荐

  1. Manacher算法(马拉车算法)浅谈

    什么是Manacher算法? 转载自百度百科 Manachar算法主要是处理字符串中关于回文串的问题的,它可以在 O(n) 的时间处理出以字符串中每一个字符为中心的回文串半径,由于将原字符串处理成两倍 ...

  2. 洛谷 2344 奶牛抗议 Generic Cow Protests, 2011 Feb

    [题解] 我们可以轻松想到朴素的状态转移方程,但直接这样做是n^2的.所以我们考虑采用树状数组优化.写法跟求逆序对很相似,即对前缀和离散化之后开一个权值树状数组,每次f[i]+=query(sum[i ...

  3. JavaScript学习总结(12)——2016 年 7 个顶级 JavaScript 框架

    当涉及到Web开发时,JavaScript框架往往是一些开发人员和企业最受欢迎的平台.可能,你有机会尝试过一两个顶级的JavaScript框架,但你仍然有点不确定哪个才是最佳的最值得掌握的,或者哪个值 ...

  4. 分块试水--CODEVS4927 线段树练习5

    模板 #include<stdio.h> #include<algorithm> #include<string.h> #include<stdlib.h&g ...

  5. cpus Vs cpu period and cpu quota

    1.  https://docs.oracle.com/cd/E37670_01/E75728/html/section-zb1_wqw_gt.html To control a container' ...

  6. Spring/Maven/MyBatis配置文件结合properties文件使用

    使用properties文件也叫注入,比如把一些常用的配置项写入到这个文件,然后在Spring的XML配置文件中使用EL表达式去获取. 这种方式不只Spring可以使用,同样MyBatis也可以使用, ...

  7. Centos7: 设置UTC时区

    timedatectl set-timezone UTC

  8. C/C++异常处理机制

    1.C语言异常处理   1.1 异常终止   标准C库提供了abort()和exit()两个函数,它们可以强行终止程序的运行,其声明处于<stdlib.h>头文件中.这两个函数本身不能检测 ...

  9. Azure Event hub usage

    1. create event hub on azure watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/40 ...

  10. python-pexpect_02ssh

    #!/usr/bin/env python """ This runs a command on a remote host using SSH. At the prom ...