信号量 Semaphore

来源:互联网 发布:linux认证工程师 编辑:程序博客网 时间:2024/05/16 05:20
  1. 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
  2. 同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源
  3. 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
原创粉丝点击