zoukankan      html  css  js  c++  java
  • 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)放入两个信号量。

  • 相关阅读:
    一些特效,不断更新
    关于cin输入字符串
    开辟二维数组
    c++ 有关webBrowser控件的一些整理
    WebBrowser 常用方法
    WebRequest和WebBrowser同时登陆,使用同一个sessionID
    delphi 编写的com 对象 用php调用的实例
    Two math problems in http://projecteureka.org sumitted by me.
    delphi dll 实例 与 dll窗体实例
    SSH酒店点菜系统笔记
  • 原文地址:https://www.cnblogs.com/kitor/p/11334934.html
Copyright © 2011-2022 走看看