信号量 Semaphore
来源:互联网 发布:linux认证工程师 编辑:程序博客网 时间:2024/05/16 05:20
- 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
- 同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源
- Semaphore、synchronized和ReentrantLock同步
import java.util.Random;import java.util.concurrent.Semaphore;public class Main { // 5个厕所 private static Semaphore semaphore = new Semaphore(5); // 上厕所的过程 private static class ToiletRunnable implements Runnable { private int i; public ToiletRunnable(int i) { this.i = i; } @Override public void run() { try { semaphore.acquire(); Random random=new Random(); Thread.sleep(random.nextInt(2000)); System.out.println("第"+i+"个人已经上完厕所"); semaphore.release(); System.out.println("还剩"+semaphore.availablePermits()+"个空厕所"); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { // 20个要上厕所的人 for (int i = 0; i < 20; i++) { Thread thread = new Thread(new ToiletRunnable(i)); thread.join(); thread.start(); } }}
源码:
public class Semaphore implements java.io.Serializable { // 不公平锁 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 (;;) { if (hasQueuedPredecessors()) return -1; int available = getState(); int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; } } } public Semaphore(int permits) { // 默认不公平锁 sync = new NonfairSync(permits); } ...}
acquire()
public void acquire() throws InterruptedException { sync.acquireSharedInterruptibly(1); } public final void acquireSharedInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (tryAcquireShared(arg) < 0) // 先执行自减 doAcquireSharedInterruptibly(arg); } // AQS模板方法 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; } } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } } // 重写tryAcquireShared方法的类 static final class NonfairSync extends Sync { private static final long serialVersionUID = -2694183684443567898L; NonfairSync(int permits) { super(permits); } protected int tryAcquireShared(int acquires) { // 调用:成功大于0->执行,失败小于0->继续阻塞 return nonfairTryAcquireShared(acquires); } // state>acquires ->返回true,否则返回false final int nonfairTryAcquireShared(int acquires) { for (;;) { int available = getState(); int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; } } }
参考闭锁源码部分代码
release()
public void release() { sync.releaseShared(1); } public final boolean releaseShared(int arg) { if (tryReleaseShared(arg)) { // 先执行state自减,再唤醒线程 doReleaseShared(); return true; } return false; } 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)) // state通过cas自增 return true; } }
0 0
- 信号量semaphore
- 信号量Semaphore
- 信号量semaphore
- 信号量Semaphore
- 信号量Semaphore
- 信号量Semaphore
- 信号量semaphore
- semaphore信号量
- 信号量Semaphore
- 信号量 semaphore
- 信号量 semaphore
- 信号量Semaphore
- Semaphore信号量
- 信号量semaphore
- 信号量Semaphore
- Semaphore (信号量)
- Semaphore(信号量)
- 信号量(Semaphore)
- HDU 1079 Calendar Game (博弈 sg函数)
- 解决Ubuntu 16下编译Qt 5报错:cannot find -lGL
- 前端工程化的理解
- Spring JdbcTemplate方法详解
- 无论什么颜色的奖牌,都是无数汗水铸成的!
- 信号量 Semaphore
- TestNG中的组groups概念
- 简易加密工具类
- 关于扩展欧几里得算法的一些资料
- nand flash驱动的编写
- 微软面试百题002——返回优先级的栈
- 文章标题
- Java Exception 捕获和展示
- hdu 2841 Visible Trees 容斥,分解质因数