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 理解为 ...
随机推荐
- System V共享内存介绍
(一)简单概念 共享内存作为一种进程间通信的方式,其相较于其他进程间通信方式而言最大的优点就是数据传输速率快.其内部实现的方式采用了Linux进程地址空间中的mmap文件映射区,将文件内容直接映射到各 ...
- [New learn] NSOperation基本使用
1.简介 NS(基于OC语言)是对GCD(基于C语言)的封装,让开发者能够更加友好的方便的去使用多线程技术. 2.NSOperation的基本使用 NSOperation是抽象类,所以如果要使用NSO ...
- 3.Python3标准库--数据结构
(一)enum:枚举类型 import enum ''' enum模块定义了一个提供迭代和比较功能的枚举类型.可以用这个为值创建明确定义的符号,而不是使用字面量整数或字符串 ''' 1.创建枚举 im ...
- Leetcode 之Largest Rectangle in Histogram(40)
又是一道构思巧妙的题,暴力求解复杂度太高,通过构造一个递增栈来解决:如果当前元素小于栈顶元素,则说明栈内已经构成一个 递增栈,则分别计算以每个元素为最低值的面积:反之,则入栈. int largest ...
- eetcode 之String to Integer (atoi)(28)
字符串转为数字,细节题.要考虑空格.正负号,当转化的数字超过最大或最小是怎么办. int atoi(char *str) { int len = strlen(str); ; ; ; while (s ...
- 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记8——载入三维模型&Alpha混合技术&深度测试与Z缓存
第17章 三维游戏模型的载入 主要是如何从3ds max中导出.X文件,以及如何从X文件加载三维模型到DirextX游戏程序里.因为复杂的3D物体,要用代码去实现,那太反人类了,所以我们需要一些建模软 ...
- hive的窗口函数1
Hive中提供了越来越多的分析函数,用于完成负责的统计分析.抽时间将所有的分析窗口函数理一遍,将陆续发布.今天先看几个基础的,SUM.AVG.MIN.MAX.用于实现分组内所有和连续累积的统计. 1. ...
- 基础平台为第三方应用接入提供oauth2认证接口
oauth2开放认证协议原理及案例分析 http://blog.csdn.net/volcan1987/article/details/7287605 谈谈基于OAuth 2.0的第三方认证 [上篇] ...
- [水煮 ASP.NET Web API2 方法论](1-8)添加 Session 状态
问题 ASP.NET Web API 构建 Web 应用程序时,要求使用 Session 在服务器存储一些用户特定的信息 解决方案 ASP.NET Web API 不支持 Session,因为 API ...
- spawn-fcgi出错处理
/usr/local/nginx/sbin/spawn-fcgi -a 127.0.0.1 -p 9002 -C 25 -f /usr/local/nginx/cgibin/lzgFastCGI 添加 ...