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 理解为 ...
随机推荐
- selenium在爬虫领域的初涉(自动打开网站爬取信息)
selenium简介 Selenium 是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.这个工具的主要功能包括:测试与浏览器的兼容性--测试你的应 ...
- Perl6 Bailador框架(3):路径匹配
use v6; use Bailador; =begin pod 注意的是, 当/:one设置时 虽然你有/admin或/about, 但这个/:one不会跟现有的匹配 只跟没有的匹配: 也就是说, ...
- 【EverydaySport】健身笔记——动态牵拉
动态牵拉,包含了动态和牵拉两个概念.动态牵拉要求牵拉的过程要伴随着走路,即行进中牵拉,动态牵拉不仅可以使得肌肉得到延展,还可以激活肌肉协同工作,发展协调性.灵活性.进行动态牵拉时每个动作要进行5~10 ...
- 【swupdate文档 二】许可证
许可证 SWUpdate是免费软件.它的版权属于Stefano Babic和其他许多贡献代码的人(详情请参阅实际源代码和git提交信息). 您可以根据自由软件基金会发布的GNU通用公共许可证第2版的条 ...
- python manage.py 命令
在用命令django‐admin.py startproject <工程目录>建立一个django工程文件时,会生成一个manage.py文件,那么这个manage.py到底可以干嘛呢? ...
- git学习资源合集
git官网 Pro git 电子书,这里还有中文版,这也是官方推荐的. 再加一个廖雪峰的简明git教程.
- Python3发送qq邮件,测试通过
import smtplib from email.mime.text import MIMEText # 收件人列表 mail_namelist = ["10402852@qq.com&q ...
- 详解WordPress中简码格式标签编写的基本方法
WordPress 简码是一种类似于论坛标签的东西,格式类似于把尖括号换成中括号的 Html 标签.简码很多人叫做短代码,但官方的翻译应该是简码,在这里纠正一下. 简码的开发的逻辑比较简单,主要就是添 ...
- es6数组必看太实用了
随着前后分离,前端人员也要写大量的逻辑代码,es5很多地方尤其是数据工具大拿数组,很多时候都是捉襟见肘. 继而,es6为我们扩展了很多good的工具和方法,让我们一起学习es6吧. 1原型方法from ...
- npoi的基本操作
////自动换行 ////自动换行翻译成英文其实就是Wrap的意思,所以这里我们应该用WrapText属性,这是一个布尔属性 //style6. ...