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信号量的主要内容,如果未能解决你的问题,请参考以下文章

Java 中的互斥量和信号量是啥?主要区别是啥?

Java 信号量代码演练

java信号量

JAVA线程同步 信号量

Java 信号量 Semaphore 介绍

java中的信号量Semaphore