jdk 源码分析(17)java Semaphore 源码解析及与lock对比
来源:互联网 发布:大连爱知时计 编辑:程序博客网 时间:2024/05/22 07:09
如果说countDownLatch和lock 相似,semaphore和lock原理基本就是相同了。如果你对lock过程不了解,建议先看
(参考lock:jdk 源码分析(7)java ReentrantLock结构)
1)定义对比
semaphore
public Semaphore(int permits) { sync = new NonfairSync(permits);}
ReentrantLock
public ReentrantLock() { sync = new NonfairSync();}
默认都是使用非公平Sync,公平Sync是先到先得,非公平是先前获取一次值,然后才排队。
2)获取信号量和获取lock对比
acquire():会调用acquireSharedInterruptibly,首先会去判断是否state 是否已经达到能请求的数量,如果没有就直接返回false,让线程继续,否则会执行doAcquireSharedInterruptibly加入队列中,然后park
public final void acquireSharedInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (tryAcquireShared(arg) < 0) doAcquireSharedInterruptibly(arg);}
lock(),会调用这个方法
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt();}
上面的doAcquireSharedInterruptibly方法,加入队列是为了unpark 的时候能找到线程。
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
//加入队列
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) {
int r = tryAcquireShared(arg);
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
failed = false;
return;
}
}
//park 一下
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
3)release和unlock对比release 会调用的方法,又是惊人的相似,先前改变state到可以使用的数目,然后去队列里释放相应数量的线程,不让他们等待了。
public final boolean releaseShared(int arg) { if (tryReleaseShared(arg)) { doReleaseShared(); return true; } return false;}
unlock会调用的方法
public final boolean release(int arg) { if (tryRelease(arg)) { Node h = head; if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false;}
4)对比release具体实现,是不是很相似。
上面的doReleaseShared方法
private void doReleaseShared() { for (;;) { Node h = head; if (h != null && h != tail) { int ws = h.waitStatus; if (ws == Node.SIGNAL) { if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0)) continue; // loop to recheck cases unparkSuccessor(h); } else if (ws == 0 && !compareAndSetWaitStatus(h, 0, Node.PROPAGATE)) continue; // loop on failed CAS } if (h == head) // loop if head changed break; }}
lock的release。
public final boolean release(int arg) { if (tryRelease(arg)) { Node h = head; if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false;}
总结:
应该可以说Semaphore 如果说是一种特殊的lock:(因为大家首先首先lock才这么说,应该是lock是一种特殊的Semaphore)
1)lock 是独占,一人享用,而Semaphore是一个多人使用,lock是电影院的VIP单人间,而Semaphore是大厅。
2)lock和Semaphore都需要排队,都有两种排队方式:公平和非公平。
3)lock和Semaphore都是改变state变量,只是lock争夺0变成1,而Semaphore是争一个非零的值,因此几率大很多。
4)如果初始是将permits也是就是state 置为1,那么Semaphore就和lock没区别了。
阅读全文
0 0
- jdk 源码分析(17)java Semaphore 源码解析及与lock对比
- jdk 源码分析(8)java synchronized和锁lock对比
- 《Java源码分析》:Semaphore
- 《Java源码分析》:Semaphore
- jdk 源码分析(15)java CountDownLatch 源码解析
- jdk 源码分析(16)java CyclicBarrier 源码解析
- jdk 源码分析(2)java hashtable的结构及hashMap对比
- JDK 源码解析 —— Semaphore
- Java 并发 --- Semaphore源码分析
- 根据AQS推测Semaphore及源码分析
- Java多线程系列(十)—Semaphore源码分析
- Java并发之Semaphore的源码分析
- android源码解析(6)--HandlerThread分析及使用对比
- JDK源码解析---ArrayList分析
- JUC - Semaphore 源码分析
- Semaphore 源码分析
- java ConcurrentSkipListMap原理分析及源码解析
- jdk 源码分析(0) java 源码分析汇总
- [Azure]ARM虚拟机整机磁盘快照[3]——清空虚拟机快照
- Java SE 6.0新特性体验(下篇)
- 欢迎使用CSDN-markdown编辑器
- 303. Range Sum Query
- Redis实战之Win7 64 + VS2013 + Redis 3.0 订阅和发布
- jdk 源码分析(17)java Semaphore 源码解析及与lock对比
- 如何减少访问磁盘的次数,减少访问磁盘的次数
- IO流--将单级文件夹下的文件复制到目标文件夹下,并重命名所有文件
- Linux fedora中安装Parallels Tools
- IO流--多级文件夹下的所有目录复制到指定目录下
- Unity官方文档的小笔记
- Result Maps collection does not contain value for java.lang.Integer
- SMO优化算法(实现SVM)
- dsp定点运算基本方法