先做总结:

1、Semaphore是什么?

Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。

把它比作是控制流量的红绿灯,比如XX马路要限制流量,只允许同时有一百辆车在这条路上行使,其他的都必须在路口等待,所以前一百辆车会看到绿灯,可以开进这条马路,后面的车会看到红灯,不能驶入XX马路,但是如果前一百辆中有五辆车已经离开了XX马路,那么后面就允许有5辆车驶入马路,这个例子里说的车就是线程,驶入马路就表示线程在执行,离开马路就表示线程执行完成,看见红灯就表示线程被阻塞,不能执行。

2、Semaphore实现原理:

(1)semaphore实际是允许count个线程同时获取的共享锁。(semaphore = new Semaphore(count); 通过AQS实现,count即state)

(2)semaphore.acquire(); 获取semaphore的锁,

state>0:还有数量,可以获取锁,state - 1;

state<=0:线程数量已满,不能获取锁,需要将线程挂起并放入等待队列;

(3)semaphore.release(); 释放semaphore的锁,就是将 state+1 释放成功后,唤醒同步队列中的线程

一、应用举例

/*** 为了简单起见我们假设停车场仅有5个停车位,一开始停车场没有车辆所有车位全部空着,然后先后到来三辆车,停车场车位够,安排进去停车。

* 然后又来三辆,这个时候由于只有两个停车位,所有只能停两辆,其余一辆必须在外面候着,直到停车场有空车位。

* 当然以后每来一辆都需要在外面候着。当停车场有车开出去,里面有空位了,则安排一辆车进去(至于是哪辆 要看选择的机制是公平还是非公平)。

*

* 从程序角度看,停车场就相当于信号量Semaphore,其中许可数为5,车辆就相对线程。

* 当来一辆车时,许可数就会减 1 ,当停车场没有车位了(许可书 ==0 ),其他来的车辆需要在外面等候着。

* 如果有一辆车开出停车场,许可数 + 1,然后放进来一辆车。*/

classSemaphoreTest {static classParking {//信号量

privateSemaphore semaphore;

Parking(intcount) {

semaphore= newSemaphore(count);

}public voidpark() {try{//获取信号量

semaphore.acquire();long time = (long) (Math.random() * 10);

System.out.println(Thread.currentThread().getName()+ "进入停车场,停车" + time + "秒...");

Thread.sleep(time);

System.out.println(Thread.currentThread().getName()+ "开出停车场...");

}catch(InterruptedException e) {

e.printStackTrace();

}finally{

semaphore.release();

}

}

}static class Car extendsThread {

Parking parking;

Car(Parking parking) {this.parking =parking;

}

@Overridepublic voidrun() {

parking.park();//进入停车场

}

}public static voidmain(String[] args) {

Parking parking= new Parking(3);for (int i = 0; i < 5; i++) {newCar(parking).start();

}

}/**输出结果

* Thread-1进入停车场,停车2秒...

* Thread-2进入停车场,停车5秒...

* Thread-0进入停车场,停车3秒...

* Thread-1开出停车场...

* Thread-3进入停车场,停车0秒...

* Thread-3开出停车场...

* Thread-4进入停车场,停车0秒...

* Thread-4开出停车场...

* Thread-0开出停车场...

* Thread-2开出停车场...*/}

二、类结构

public class Semaphore implementsjava.io.Serializable {private finalSync sync;abstract static class Sync extendsAbstractQueuedSynchronizer {}static final class FairSync extendsSync {}static final class NonfairSync extendsSync {}

}

三、原理解析

//new Semaphore(count),将AQS的state设置成许可数量count

semaphore = newSemaphore(count);public Semaphore(intpermits) {

sync= newNonfairSync(permits);

}

Sync(intpermits) {

setState(permits);

}

/*** 获取semaphore的锁,

* 获取到锁就可以继续操作,没有获取到锁就进入同步队列挂起*/semaphore.acquire();public final void acquireSharedInterruptibly(intarg)throwsInterruptedException {if(Thread.interrupted())throw newInterruptedException();if (tryAcquireShared(arg) < 0)

doAcquireSharedInterruptibly(arg);

}/*** state>0:还有数量,可以获取锁

* state<=0:线程数量已满,不能获取锁,需要将线程挂起*/

final int nonfairTryAcquireShared(intacquires) {for(;;) {int available =getState();int remaining = available -acquires;if (remaining < 0 ||compareAndSetState(available, remaining))returnremaining;

}

}

/*** 释放semaphore的锁,就是将state+1

* 释放成功后,唤醒同步队列中的下一个线程*/semaphore.release();public voidrelease() {

sync.releaseShared(1);

}public final boolean releaseShared(intarg) {if(tryReleaseShared(arg)) {

doReleaseShared();return true;

}return false;

}protected final boolean tryReleaseShared(intreleases) {for(;;) {int current =getState();int next = current +releases;if (next < current) //overflow

throw new Error("Maximum permit count exceeded");if(compareAndSetState(current, next))return true;

}

}

内容来源于网络如有侵权请私信删除

java semaphorewa_Java并发(十五):并发工具类——信号量Semaphore相关推荐

  1. Java 并发编程之同步工具类信号量 Semaphore

    Semaphore 可以理解为一个阈值,正在进行的操作数量不能超过此阈值,可以用来限制资源的访问,或者控制某个队列中对象的个数,也就是控制同时执行的线程的数量. 主要有acquire,release两 ...

  2. java 静态类 安全_Java静态static工具类线程安全问题研究

    针对静态方法有以下一些前提: 静态方法和实例方法的区别是静态方法只能引用静态变量,静态方法通过类名来调用,实例方法通过对象实例来调用 每个线程都有自己的线程栈,栈与线程同时创建,每一个虚拟机线程都有自 ...

  3. java学习记录十五:集合二Collections、Set、Map

    java学习记录十五:集合二 一.Collections工具类 一.解释 二.常用方法 1.打乱集合顺序 2.按照默认规则排序 3.按指定规则排序 4.批量添加元素 二.可变参数 一.解释 二.写法 ...

  4. PyTorch框架学习十五——可视化工具TensorBoard

    PyTorch框架学习十五--可视化工具TensorBoard 一.TensorBoard简介 二.TensorBoard安装及测试 三.TensorBoard的使用 1.add_scalar() 2 ...

  5. Java学习 第十五天

    Java学习 第十五天 第一章 StringBuilder类 1.1 字符串的不可变 1.2 StringBuilder概述 1.3 构造方法 1.4 两个常用方法 1.4.1 append方法 1. ...

  6. Java学习总结:58(Collections工具类)

    Collections工具类 Java提供了一个集合的工具类--Collections,这个工具类可以实现List.Set.Map集合的操作.Collections类的常用方法如下: No. 方法 类 ...

  7. java配置文件工具类,java项目加载配置文件的工具类

    java项目加载配置文件的工具类 package com.loadproperties; import java.io.IOException; import java.io.InputStream; ...

  8. JAVASE基础模块十五(StringBuffer类)

    JAVASE基础模块十五(StringBuffer类) public class Stbuffer { public static void main(String[] args) { //总共创建五 ...

  9. Java实现Google的S2算法工具类

    WGS84坐标系 GCJ02坐标系 BD09坐标系的各种转换 WGS84坐标系 GCJ02坐标系 BD09坐标系的各种转换 Google S2 经纬度 转 CellId 经纬度 转 cellToken ...

最新文章

  1. Spring中Bean的生命周期是怎样的
  2. SmartGit破解方法
  3. Nginx自动安装脚本
  4. extjs 前端js代码调用后台函数方法
  5. 安卓log.e函数打印示例_log1p()函数以及C ++中的示例
  6. Activiti获取当前活动(任务)的出口(动态生成提交按钮)
  7. 【图像处理】openCV库教程
  8. ffmpeg文档1:制作屏幕录像
  9. HP 瘦客户机 - 使用 ie4uinit.exe 应用时,Citrix HDX Flash 出现故障和错误
  10. Oracle数据库基本操作(windows 本地环境)
  11. Java基础知识面试题(2021年最新版,持续更新...)整理
  12. 合肥工业大学暑期“三下乡”——探访悠悠古村 发扬传统文化
  13. 复购率/回购率/新购人数
  14. 微信小程序之短信验证码
  15. 关于道家与道教的总结
  16. 区块链概念股分析 | 远光软件大涨128%,区块链或成关键因素?
  17. 和菜鸟一起学算法之二分法求极值问题
  18. “照骗”是如何炼成的?
  19. chrome浏览器导出文件提示病毒扫描失败
  20. VS语音信号处理(6) C语言调用SoundTouch进行变速不变调工程实例

热门文章

  1. 为EF DbContext生成的实体添加注释(T5模板应用)[转]
  2. 安装部署gitlab ci
  3. 数组的应用 冒泡排序
  4. Java数据库接口JDBC入门基础讲座_JDBC基础教程之CallableStatement
  5. 有滋有味了freeeim
  6. 飞鸽类能记住传书的人类
  7. 莱比锡爆料:《星际争霸2》估计明年也没戏
  8. 纽约时报》:乔布斯和苹果的“保密文化”
  9. 11个技巧让你编写出更好的Python代码,值得收藏!!
  10. 程序员修复bug的吐血过程,太形象了