信号

信号量是一种高级同步器,它维护一组可由线程获取和释放的许可。信号量可以被想象为许可的计数器,当线程获取时将递减,并在线程释放时递增。如果线程尝试获取许可数量为 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
    }
}