【Java8源码分析】并发包-Semaphore
来源:互联网 发布:种子结构网络教研总结 编辑:程序博客网 时间:2024/05/14 06:15
转载请注明出处:http://blog.csdn.net/linxdcn/article/details/72857243
Semaphore是信号量,它的作用是控制多个允许。
打个比方,一个博物馆有容纳1000人的能力(Semaphore的允许是1000),假如1500人同时来参馆,只有1000人能获得允许入馆(获得锁),其余的500则需排队(阻塞),直到馆内的人离开(释放锁)才能放人入馆。
1 如何使用
public class SemaphoreDemo { public static void main(String[] args) { for (int i = 0; i < 4; i++) { new Thread(new SemaphoreTest()).start(); } } static class SemaphoreTest implements Runnable{ public static Semaphore semaphore = new Semaphore(2, true); @Override public void run() { try { semaphore.acquire(); System.out.println(Thread.currentThread() + " getting semaphore"); Thread.sleep(1000); System.out.println(Thread.currentThread() + " realsing semaphore"); semaphore.release(); } catch (Exception e) { } } }}
程序输出
Thread[Thread-1,5,main] getting semaphoreThread[Thread-0,5,main] getting semaphoreThread[Thread-0,5,main] realsing semaphoreThread[Thread-1,5,main] realsing semaphoreThread[Thread-3,5,main] getting semaphoreThread[Thread-2,5,main] getting semaphoreThread[Thread-2,5,main] realsing semaphoreThread[Thread-3,5,main] realsing semaphore
2 源码分析
Semaphore的内部实现也是基于AQS类的,不了解的可以参考AbstractQueuedSynchronizer同步器一文。
Semaphore
与ReetrantLock
一样有公平锁与非公平锁,ReetrantLock
可以看成是Semaphore
许可为1的特例,在实现中,Semaphore
中的state
代表可用的许可,在ReetrantLock
中,state
大于0代表线程重入的次数
2.1 非公平锁
(1)获取许可
final int nonfairTryAcquireShared(int acquires) { for (;;) { int available = getState(); int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; }}
remaining表示请求许可后的许可剩余值,如果
- remaining < 0,许可不足,挂起线程,并且添加线程至排队队列
- remaining > 0,自旋尝试更新state值,更新成功获得许可
从代码可以看到,当一个线程申请许可时,无需判断是否有线程在排队队列中,体现非公平性
(2)释放许可
protected final boolean tryReleaseShared(int releases) { for (;;) { int current = getState(); int next = current + releases; if (next < current) // overflow throw new Error("Maximum permit count exceeded"); if (compareAndSetState(current, next)) return true; }}
自旋采用CAS算法更新state状态
2.2 公平锁
(1)获取许可
protected int tryAcquireShared(int acquires) { for (;;) { // 先判断排队队列中是否为空 if (hasQueuedPredecessors()) return -1; int available = getState(); int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; }}
公平锁的机制比非公平锁多了判断排队队列是否为空,如果有其他线程在排队队列中,则该线程也需转入排队队列,体现公平性。
3 总结
- Semaphore是不可重入的,同一线程多次获取Semaphore是会消耗许可的,例如一个Semaphore的许可为2,同一线程调用了3次acquire函数,该线程会被阻塞
参考
http://www.jianshu.com/p/0090341c6b80
转载请注明出处:http://blog.csdn.net/linxdcn/article/details/72857243
阅读全文
0 0
- 【Java8源码分析】并发包-Semaphore
- 【Java8源码分析】并发包-AtomicInteger
- 【Java8源码分析】并发包-CopyOnWriteArrayList
- 【Java8源码分析】并发包-CountDownLatch
- 【Java8源码分析】并发包-CyclicBarrier
- Java 并发 --- Semaphore源码分析
- 【Java8源码分析】并发包-ConcurrentHashMap(一)
- 【Java8源码分析】并发包-ConcurrentHashMap(二)
- Java并发之Semaphore的源码分析
- 【Java8源码分析】locks包-AbstractQueuedSynchronizer同步器
- 【Java8源码分析】locks包-ReentrantLock
- 【Java8源码分析】locks包-ReentrantReadWriteLock
- 【Java8源码分析】NIO包-FileChannel
- 【Java8源码分析】NIO包-Selector选择器
- 并发编程工具之三:Semaphore 用法及源码分析
- Semaphore - jdk1.5并发包
- java 并发包之Semaphore
- 《Java源码分析》:Semaphore
- 插入排序
- JNI入门(一)
- 利用keepalived构建高可用MySQL-HA
- gradle项目构建
- Rails中的 attributes 方法
- 【Java8源码分析】并发包-Semaphore
- SAP MM/PP/SD的区别与联系
- Hibernate SQL查询 addScalar()或addEntity()
- 虚拟机硬盘容量扩展以及分区挂载详细步骤
- h5 3D旋转立方体
- Python3.6 numpy opencv3.2 安装 及 ImportError: DLL load failed: 找不到指定的模块
- vue-- vue-bind:src
- 使用HEXO搭建博客平台
- 多块PCIe SSD插在同一个主板上时,Linux 对这几块SSD的命名