zoukankan      html  css  js  c++  java
  • 信号量Semaphore

    信号量Semaphore


    信号量Semaphore是一个控制访问多个共享资源的计数器,和CountDownLatch一样,其本质上是一个“共享锁”。

    Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。

    信号量Semaphore是一个非负整数(>=1)。当一个线程想要访问某个共享资源时,它必须要先获取Semaphore,当Semaphore >0时,获取该资源并使Semaphore – 1。如果Semaphore值 = 0,则表示全部的共享资源已经被其他线程全部占用,线程必须要等待其他线程释放资源。当线程释放资源时,Semaphore则+1。

    实现

    其内部也是通过队列同步器实现。

    abstract static class Sync extends AbstractQueuedSynchronizer
    

    构造函数

    也分为公平的信号量和不公平的信号量,其中默认的为不公平的。

    public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }
    public Semaphore(int permits) {
            sync = new NonfairSync(permits);
        }
    

    主要的公共方法

    //获得一个访问许可,如果没有可用资源或者被中断,则阻塞
    public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
    //对中断不敏感
    public void acquireUninterruptibly() {
        sync.acquireShared(1);
    }
    //再被调用的时候有资源则获取,否则返回false
    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 int availablePermits() {
        return sync.getPermits();
    }
    //获得并返回所有可以获得的资源数
    public int drainPermits() {
        return sync.drainPermits();
    }
    。。。
    还有三个方法就不写了
    

    使用示例

    火车站有五个停靠点,有七辆,每辆火车停2秒

    package my.syn;
    
    import java.util.concurrent.Semaphore;
    
    /**
     * @ClassName: MyStation
     * @author: Yang.X.P
     * @date: 2018-09-18 09:22
     **/
    public class MyStation {
        static Semaphore semaphore = new Semaphore(5);
    
        public static void main(String[] args) {
            Train train = new Train();
            for (int i = 0; i < 7; i++) {
                Thread trainThread = new Thread(train);
                trainThread.start();
            }
        }
    }
    
    class Train implements Runnable {
    
        @Override
        public void run() {
            if(MyStation.semaphore.availablePermits() ==0) {
                System.out.println(Thread.currentThread().getName()+"火车暂无可停靠点,正在等待" );
            }
            try {
                MyStation.semaphore.acquire();
                System.out.println(Thread.currentThread().getName()+"火车进站停2秒" );
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName()+"火车开出停靠点" );
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            MyStation.semaphore.release();
        }
    }
    

    参考资料:

    http://cmsblogs.com/?p=2263

  • 相关阅读:
    散列表(Hash Table)
    MVC中TextBox事件
    AJAX控制DropDownList两级联动
    唯一标示
    检查对象属性是否有空值
    foreach枚举div控制单个显示
    JS获取DropDownList其中一项的文本值
    随便
    MVC常用
    不可用输入框
  • 原文地址:https://www.cnblogs.com/fruitknife/p/9703148.html
Copyright © 2011-2022 走看看