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

      Semaphore用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量。计数信号量还可以用来实现某种资源池,或者对容器施加边界。

      Semaphore可以用于实现资源池。例如数据库连接池。我们可以构造一个固定长度的资源池,当池为空时,请求资源将会失败,但你真正希望看到的行为是阻塞而不是失败,并且当池为非空时解除阻塞,如果将Semaphore的计数值初始化为池的大小,并在池中获取一个资源之前首先调用accquire方法获取一个许可,在将资源返回给池之后调用release释放许可,那么accquire将一直阻塞直到资源池不为空。

      Semaphore还可以将任何一种容器变成有界阻塞容器。

      有界缓冲类也是用Semaphore实现。

    下面是自己实现一个简单HashSet的有界阻塞容器。

    package com.citi.test.mutiplethread.demo0503;
    
    import java.util.Collections;
    import java.util.HashSet;
    import java.util.Set;
    import java.util.concurrent.Semaphore;
    
    public class BoundedHashSet<T> {
        private final Set<T> set;
        private final Semaphore sem;
        public BoundedHashSet(int bound) {
            this.set = Collections.synchronizedSet(new HashSet<T>());
            this.sem = new Semaphore(bound);
        }
        
        public boolean add(T o) throws InterruptedException{
            sem.acquire();
            boolean wasAdded=false;
            try{
                wasAdded=set.add(o);
                return wasAdded;
            }
            finally{
                if(!wasAdded){
                    sem.release();
                }
            }
        }
        public boolean remove(Object o){
            boolean wasRemoved=set.remove(o);
            if(wasRemoved){
                sem.release();
            }
            return wasRemoved;
        }
    
        public Set<T> getSet() {
            return set;
        }
        
    }
    View Code

    原理:

    内部是用AQS框架实现的。

    private static final long serialVersionUID = -3222578661600680210L;
    /** All mechanics via AbstractQueuedSynchronizer subclass */
    private final Sync sync;
    
    //获取信号量。 阻塞方法
    public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
    
    //释放信号量
    public void release() {
        sync.releaseShared(1);
    }
    View Code
  • 相关阅读:
    hdu1072 逃离迷宫系列 bfs
    hdu1495 倒水bfs
    hdu 1548 A strange lift (bfs)
    hdu1728 逃离迷宫bfs
    hdu1548 奇怪的电梯 dfs dijkstra bfs都可以,在此奉上dfs
    delphi 窗体的位置和高宽度-TForm:Letf、Top、Width、Height、ClientWidth、ClientHeight
    Delphi 鼠标控制函数GetCursorPos、SetCursorPos
    Delphi CoCreateGuid()函数 获取GUID
    Delphi出现“borland license information was found,but it is not valid for delphi”的错误,无法运行的解决方法
    一维条形码生成与识别技术
  • 原文地址:https://www.cnblogs.com/liumy/p/11616360.html
Copyright © 2011-2022 走看看