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 理解为 ...
随机推荐
- 448D - Codeforces
D. Multiplication Table time limit per test 1 second memory limit per test 256 megabytes Bizon the C ...
- 网络知识===wireshark抓包数据分析(一)
wireshark分析: 上图是我进行一个HTTP协议的下载,文件内容大概是1.7M左右. 抓包数据: https://files.cnblogs.com/files/botoo/wireshark% ...
- MySQL-5.5.49安装、多实例、主从复制
源码安装mysql yum install ncurses-devel libaio-devel -y mkdir /server/tools -p cd /server/tools wget htt ...
- C++中string类的方法
C++ string类的方法 具体每个方法怎么使用,可以参考相应的链接. 总的链接为http://www.cplusplus.com/reference/string/string/(C++参考文档) ...
- Mac 使用自带的Ruby 安装brew
Homebrew简称brew,OSX上的软件包管理工具,在Mac终端可以通过brew安装.更新.卸载软件. 首先要安装brew,在 mac 中使用finder 搜索 终端(terminal)打开命令行 ...
- eclipse 配置jsp
1.安装jdk和jre 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html ...
- python的多线程、多进程代码示例
python多进程和多线程的区别:python的多线程不是真正意义上的多线程,由于python编译器的问题,导致python的多线程存在一个PIL锁,使得python的多线程的CPU利用率比预期的要低 ...
- Zookeeper之Curator(1)客户端对节点的一些监控事件的api使用
<一>节点改变事件的监听 public class CauratorClientTest { //链接地址 private static String zkhost="172.1 ...
- ubuntu 软件包(package)更换源(source)为阿里云镜像 update&upgrade
在ubuntu下用apt-get install安装软件时,发现package list中没有所需的软件, 估计可能是package list太旧了,于是需要apt-get update & ...
- python中的is, ==与对象的相等判断
在java中,对于两个对象啊a,b,若a==b表示,a和b不仅值相等,而且指向同一内存位置,若仅仅比较值相等,应该用equals.而在python中对应上述两者的是‘is’ 和‘==’. (1) py ...