訊號

訊號量是一種高階同步器,它維護一組可由執行緒獲取和釋放的許可。訊號量可以被想象為許可的計數器,當執行緒獲取時將遞減,並線上程釋放時遞增。如果執行緒嘗試獲取許可數量為 0,則執行緒將阻塞直到許可證可用(或直到執行緒被中斷)。

訊號量初始化為:

Semaphore semaphore = new Semaphore(1); // The int value being the number of permits

Semaphore 建構函式接受另一個布林引數以實現公平性。設定為 false 時,此類不保證執行緒獲取許可的順序。當公平性設定為 true 時,訊號量保證選擇呼叫任何獲取方法的執行緒以按照處理這些方法的呼叫的順序獲得許可。它以下列方式宣告:

Semaphore semaphore = new Semaphore(1, true);

現在讓我們看一下 javadocs 的一個例子,其中 Semaphore 用於控制對項池的訪問。在此示例中使用訊號量來提供阻塞功能,以確保在呼叫 getItem() 時始終可以獲取專案。

class Pool {
    /*
     * Note that this DOES NOT bound the amount that may be released!
     * This is only a starting value for the Semaphore and has no other
     * significant meaning UNLESS you enforce this inside of the
     * getNextAvailableItem() and markAsUnused() methods
     */
    private static final int MAX_AVAILABLE = 100;
    private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);

    /**
     * Obtains the next available item and reduces the permit count by 1. 
     * If there are no items available, block.
     */
    public Object getItem() throws InterruptedException {
        available.acquire();
        return getNextAvailableItem();
    }

    /**
     * Puts the item into the pool and add 1 permit.
     */
    public void putItem(Object x) {
        if (markAsUnused(x))
            available.release();
    }

    private Object getNextAvailableItem() {
        // Implementation
    }

    private boolean markAsUnused(Object o) {
        // Implementation
    }
}