java信号量
Posted kitor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java信号量相关的知识,希望对你有一定的参考价值。
维基百科解释的信号量概念如下
信号量(英语:semaphore)又称为信号标,是一个同步对象,用于保持在0至指定最大值之间的一个计数值。当线程完成一次对该semaphore对象的等待(wait)时,该计数值减一;当线程完成一次对semaphore对象的释放(release)时,计数值加一。当计数值为0,则线程等待该semaphore对象不再能成功直至该semaphore对象变成signaled状态。semaphore对象的计数值大于0,为signaled状态;计数值等于0,为nonsignaled状态.
semaphore对象适用于控制一个仅支持有限个用户的共享资源,是一种不需要使用忙碌等待(busy waiting)的方法。
信号量的概念是由荷兰计算机科学家艾兹赫尔·戴克斯特拉(Edsger W. Dijkstra)发明的,广泛的应用于不同的操作系统中。在系统中,给予每一个行程一个信号量,代表每个行程目前的状态,未得到控制权的行程会在特定地方被强迫停下来,等待可以继续进行的讯号到来。如果信号量是一个任意的整数,通常被称为计数讯号量(Counting semaphore),或一般讯号量(general semaphore);如果信号量只有二进位的0或1,称为二进位讯号量(binary semaphore)。在linux系统中,二进位讯号量(binary semaphore)又称互斥锁(Mutex)。
********************************************************
博客正文:Java中的信号量是类Semaphore源码如下
package java.util.concurrent; import java.util.Collection; import java.util.concurrent.locks.AbstractQueuedSynchronizer; public class Semaphore implements java.io.Serializable private static final long serialVersionUID = -3222578661600680210L; /** All mechanics via AbstractQueuedSynchronizer subclass */ private final Sync sync; abstract static class Sync extends AbstractQueuedSynchronizer private static final long serialVersionUID = 1192457210091910933L; Sync(int permits) setState(permits); final int getPermits() return getState(); final int nonfairTryAcquireShared(int acquires) for (;;) int available = getState(); int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; 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; final void reducePermits(int reductions) for (;;) int current = getState(); int next = current - reductions; if (next > current) // underflow throw new Error("Permit count underflow"); if (compareAndSetState(current, next)) return; final int drainPermits() for (;;) int current = getState(); if (current == 0 || compareAndSetState(current, 0)) return current; /** * NonFair version */ static final class NonfairSync extends Sync private static final long serialVersionUID = -2694183684443567898L; NonfairSync(int permits) super(permits); protected int tryAcquireShared(int acquires) return nonfairTryAcquireShared(acquires); /** * Fair version */ static final class FairSync extends Sync private static final long serialVersionUID = 2014338818796000944L; 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; /** * Creates a @code Semaphore with the given number of * permits and nonfair fairness setting. * * @param permits the initial number of permits available. * This value may be negative, in which case releases * must occur before any acquires will be granted. */ public Semaphore(int permits) sync = new NonfairSync(permits); public Semaphore(int permits, boolean fair) sync = fair ? new FairSync(permits) : new NonfairSync(permits); public void acquire() throws InterruptedException sync.acquireSharedInterruptibly(1); public void acquireUninterruptibly() sync.acquireShared(1); public boolean tryAcquire() return sync.nonfairTryAcquireShared(1) >= 0; public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); public void release() sync.releaseShared(1); public void acquire(int permits) throws InterruptedException if (permits < 0) throw new IllegalArgumentException(); sync.acquireSharedInterruptibly(permits); public void acquireUninterruptibly(int permits) if (permits < 0) throw new IllegalArgumentException(); sync.acquireShared(permits); public boolean tryAcquire(int permits) if (permits < 0) throw new IllegalArgumentException(); return sync.nonfairTryAcquireShared(permits) >= 0; public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException if (permits < 0) throw new IllegalArgumentException(); return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout)); public void release(int permits) if (permits < 0) throw new IllegalArgumentException(); sync.releaseShared(permits); public int availablePermits() return sync.getPermits(); public int drainPermits() return sync.drainPermits(); protected void reducePermits(int reduction) if (reduction < 0) throw new IllegalArgumentException(); sync.reducePermits(reduction); public boolean isFair() return sync instanceof FairSync; public final boolean hasQueuedThreads() return sync.hasQueuedThreads(); public final int getQueueLength() return sync.getQueueLength(); protected Collection<Thread> getQueuedThreads() return sync.getQueuedThreads(); public String toString() return super.toString() + "[Permits = " + sync.getPermits() + "]";
它有两个构造,单一参数的是构造一出一个不公平锁的信号量类,两个参数的第一个参数是指定信号数,第二个是是否使用公平锁。关于详细的介绍查看Java并发之Semaphore
它的简单使用如下
定义一个信号量对象semaphore,在线程执行之前通过semaphore.acquire()进行信号量的获取,如果得到permit信号当前线程就会执行,否则当前线程不会被执行,线程执行之后一定要release()释放信号。
当初始化的信号量是0时,可以通过当前信号量的对象调用release(int a)放入两个信号量。
以上是关于java信号量的主要内容,如果未能解决你的问题,请参考以下文章