jdk源碼解析四之Semaphore

Semaphore

計數信號量:控制同時訪問某個特定資源的操作數量,或者同時執行某個指定操作的數量,實現某種資源池,對容器施加邊界

acquire

步驟同CountDownLatch.wait

    public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

        protected int tryAcquireShared(int acquires) {
            return nonfairTryAcquireShared(acquires);
        }
        final int nonfairTryAcquireShared(int acquires) {
        //<0才阻塞
            for (;;) {
                //獲取同步狀態的值。
                int available = getState();
                int remaining = available - acquires;
                //available爲0或者更新成功,直接返回
                if (remaining < 0 ||
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }

release

    public void release() {
        sync.releaseShared(1);
    }
        protected final boolean tryReleaseShared(int releases) {
            for (;;) {
                //獲取同步狀態的值。
                int current = getState();
                //累加
                int next = current + releases;
                //內存溢出,也就是超過了Integer範圍上限
                if (next < current) // overflow
                    throw new Error("Maximum permit count exceeded");
                //修改值返回
                if (compareAndSetState(current, next))
                    return true;
            }
        }

總結

與閉鎖和其類似,閉鎖是爲0,纔可以訪問,信號量恰恰相反,
信號量和閉鎖的區別是不是一次性的,可以重複限定多少線程可以訪問資源.
如果不限定釋放的條件,可以不停的釋放從而超過構造設置的許可個數,
建議這樣使用

   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;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章