Semaphore(信号量)源码分析
1. Semaphore
Semaphore和ReentrantReadWriteLock.ReadLock(读锁)都采用AbstractOwnableSynchronizer共享排队的方式实现。
关于AbstractQueuedSynchronizer中的独占锁和共享锁,请参考ReentrantLock(http://www.cnblogs.com/bjorney/p/8040085.html)和ReentrantReadWriteLock(http://www.cnblogs.com/bjorney/p/8064268.html)
问题:Semaphore在acquire时不检查传入的参数是否超过state最大值??? 例如,new Semaphore(5, ture || false) -> acquire(10),则调用acquire的线程将被阻塞
1)在公平模式下,之后所有调用acquire的线程都将在SyncQueue中排队而永远阻塞???
2)在非公平模式下,之后所有acquire失败而参与排队的线程都将永远阻塞???
public class Semaphore implements java.io.Serializable {
private final Sync sync;
public Semaphore(int permits) {
sync = new NonfairSync(permits); // 公平竞争,sync的锁状态(锁计数)state = permits
}
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits); // 公平竞争 || 非公平竞争
}
public void acquire() throws InterruptedException; // acquire(1)
public void acquire(int permits) throws InterruptedException { // permits必须>=0
if (permits < 0) throw new IllegalArgumentException();
sync.acquireSharedInterruptibly(permits);
}
public void acquireUninterruptibly(); // acquireUninterruptibly(1)
public void acquireUninterruptibly(int permits) { // permits必须>=0
if (permits < 0) throw new IllegalArgumentException();
sync.acquireShared(permits);
}
public boolean tryAcquire(); // tryAcquire(1)
public boolean tryAcquire(int permits) { // permits必须>=0
if (permits < 0) throw new IllegalArgumentException();
return sync.nonfairTryAcquireShared(permits) >= 0;
}
public boolean tryAcquire(long timeout, TimeUnit unit); // tryAcquire(1, timeout, unit)
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException { // permits必须>=0
if (permits < 0) throw new IllegalArgumentException();
return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
}
public void release(); // release(1)
public void release(int permits) { // permits必须>=0
if (permits < 0) throw new IllegalArgumentException();
sync.releaseShared(permits);
}
... ...
}
2. Semaphore.Sync
abstract static class Sync extends AbstractQueuedSynchronizer {
Sync(int permits) {
setState(permits);
}
final int nonfairTryAcquireShared(int acquires) { // 尝试非公平取锁
for (;;) {
// CAS(state)失败将回到此处
int available = getState(); /*记录state*/
int remaining = available - acquires;
if (remaining < 0 || compareAndSetState(available, remaining)) //remaining >= 0时/*CAS设置state -= acquires*/
return remaining; // remaining < 0:SyncQueue中排队
}
}
protected final boolean tryReleaseShared(int releases) {
for (;;) {
// CAS(state)失败将回到此处
int current = getState(); /*记录state*/
int next = current + releases;
if (next < current) throw new Error("Maximum permit count exceeded");
if (compareAndSetState(current, next)) /*CAS设置state += releases*/
return true;
}
}
... ...
}
static final class NonfairSync extends Sync {
NonfairSync(int permits) {
super(permits);
}
protected int tryAcquireShared(int acquires) { // 尝试非公平取锁
return nonfairTryAcquireShared(acquires);
}
}
static final class FairSync extends Sync {
FairSync(int permits) {
super(permits);
}
protected int tryAcquireShared(int acquires) { // 尝试公平取锁
for (;;) {
// CAS(state)失败将回到此处
if (hasQueuedPredecessors()) // SyncQueue不为空 && SyncQueue中下个待唤醒节点非当前线程所在节点
return -1; //
int available = getState(); /*记录state*/
int remaining = available - acquires;
if (remaining < 0 || compareAndSetState(available, remaining)) //remaining >= 0时/*CAS设置state -= acquires*/
return remaining;
}
}
}
Semaphore(信号量)源码分析的更多相关文章
- Java并发编程笔记之Semaphore信号量源码分析
JUC 中 Semaphore 的使用与原理分析,Semaphore 也是 Java 中的一个同步器,与 CountDownLatch 和 CycleBarrier 不同在于它内部的计数器是递增的,那 ...
- Semaphore信号量源码解析
介绍 Semaphore是什么 Semaphore可以称为信号量,这个原本是操作系统中的概念,是一种线程同步方法,配合PV操作实现线程之间的同步功能.信号量可以表示操作系统中某种资源的个数,因此可以用 ...
- go中semaphore(信号量)源码解读
运行时信号量机制 semaphore 前言 作用是什么 几个主要的方法 如何实现 sudog 缓存 acquireSudog releaseSudog semaphore poll_runtime_S ...
- Java并发包中Semaphore的工作原理、源码分析及使用示例
1. 信号量Semaphore的介绍 我们以一个停车场运作为例来说明信号量的作用.假设停车场只有三个车位,一开始三个车位都是空的.这时如果同时来了三辆车,看门人允许其中它们进入进入,然后放下车拦.以后 ...
- 源码分析:Semaphore之信号量
简介 Semaphore 又名计数信号量,从概念上来讲,信号量初始并维护一定数量的许可证,使用之前先要先获得一个许可,用完之后再释放一个许可.信号量通常用于限制线程的数量来控制访问某些资源,从而达到单 ...
- 【JUC】JDK1.8源码分析之Semaphore(六)
一.前言 分析了CountDownLatch源码后,下面接着分析Semaphore的源码.Semaphore称为计数信号量,它允许n个任务同时访问某个资源,可以将信号量看做是在向外分发使用资源的许可证 ...
- Semaphore 源码分析
Semaphore 源码分析 1. 在阅读源码时做了大量的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限,并且代码阅读起来没有 IDE 方便,所以在 github 上提供JDK1.8 的 ...
- 并发编程之 Semaphore 源码分析
前言 并发 JUC 包提供了很多工具类,比如之前说的 CountDownLatch,CyclicBarrier ,今天说说这个 Semaphore--信号量,关于他的使用请查看往期文章并发编程之 线程 ...
- Java - "JUC" Semaphore源码分析
Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例 Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了 ...
- 【JDK】JDK源码分析-Semaphore
概述 Semaphore 是并发包中的一个工具类,可理解为信号量.通常可以作为限流器使用,即限制访问某个资源的线程个数,比如用于限制连接池的连接数. 打个通俗的比方,可以把 Semaphore 理解为 ...
随机推荐
- 【hihocoder】sam1-基本概念
这题有毒…… 原本只是想复习下sam,于是写…… 后来发现自己傻了不知道怎么维护endpos…… 一气之下直接kmp拉倒,mdzz UPD:现在我好像会维护endpos了…… #include< ...
- windows下使用github
1.首先到github.com注册用户: 2.下载git,地址:http://pan.baidu.com/s/1skPpWlB(64位下载):http://pan.baidu.com/s/1skOAa ...
- MYSQL中INET_ATON()函数
例如我们现在要在一个表中查出 ip 在 192.168.1.3 到 192.168.1.20 之间的 ip 地址,我们首先想到的就是通过字符串的比较来获取查找结果,但是如果我们通过这种方式来查找,结果 ...
- OpenCV利用矩阵实现图像旋转
利用OpenCV的矩阵操作实现图像的逆时针旋转90度操作 代码 Mat src = imread("C:\\Users\\fenggl\\Desktop\\测试.jpg",MREA ...
- 【python】多个文件共用日志系统的重复打印问题
先写一个最简单的log文件: test_logging5.py #coding:utf-8 import logging logging.debug('logger debug message') l ...
- Java学习笔记(三)——静态导入,package-info,Fall-through
[前面的话] 算是真正的放松了好几天时间,没有看任何书,没有任何任务,今天是过完年后的第一天上班时间,我又开始了我的学习之路,感觉还没有老,怎么心态越来越平静了,进入工作状态,就好好努力工作,新的一年 ...
- vue-vuex安装
npm install vuex --save 然后在package.json文件的 dependencies中就看到有了一个vuex的文件 解释一下 dependencies生产环境它的意思就是上线 ...
- bzoj 2434 AC自动机 + fail指针建树 + 树状数组
思路:我们先跟着它给定的字符串走把字典树建出来,求出fail指针,我们考虑两个字符串 A和B, 如果想要求B中有多少A的子串,转换一下就是有多少个B的前缀的后缀包含A,这个在AC自动机 的状态图中很容 ...
- nginx的http负载均衡
注意:nginx自带的http服务后端检测有缺陷,无法根据状态码来检测,建议使用tengine的nginx_upstream_check_module来实现后端服务的http健康状态检测 (1)负载均 ...
- textbox获取当前光标位置,在光标后面插入字符串
左侧输入要复制的字符串,点击复制btn,将左侧字符串复制到后侧, 示例: 输入框 复制后 12345 12345 (光标落在3后) aaa 123aaa45(光标落在4后 ...