用1和0初始化的信号量之间的差异

Atu*_*mar 11 java java.util.concurrent

请告诉我有什么区别信号量用1和0初始化.如下:

public static Semaphore semOne = new Semaphore(1);
Run Code Online (Sandbox Code Playgroud)

public static Semaphore semZero = new Semaphore(0);
Run Code Online (Sandbox Code Playgroud)

Chi*_*hip 12

信号量实例的参数是可用的"许可"数.它可以是任何整数,而不仅仅是0或1.

对于semZero所有acquire()调用将阻塞,并且tryAcquire()调用将返回false,直到您执行release()

对于semOne第一次acquire()调用将成功,其余将阻止,直到第一次调用发布.

这里有很好的文章.

参数:permit - 可用的初始许可数.此值可能为负值,在这种情况下,必须在授予任何获取之前发布.

  • @ETHER 没有。如果它是 0,那么你需要在任何人获得它之前先释放它。 (2认同)

Joo*_*gen 8

构造函数参数permits(初始信号量计数器)是Semaphore.aquire()在计数器(许可)为零之前可以进行的调用次数,以及acquire()块。

1是正常值,保证只有一个线程通过acquire。

semaphore.acquire();
try {
    // Critical region
    ...
} finally {
    semaphore.release();
}
Run Code Online (Sandbox Code Playgroud)

有关0的用法,请参见此处

信号量是一种低级并发机制:当线程执行达到零阻塞时的计数器。它源于Dijkstra,其中二进制信号量 (0, 1) 是铁路信号量的隐喻,表示 pass(0 时停止,pass --permits),并在受保护轨道的末尾释放(++permits)。


小智 7

当我第一次阅读信号量的文档时,我也误解了其中的解释。我错过的要点是“...初始许可证数量...”的部分。不知何故,我认为这将是可用的最大许可证数量,但事实并非如此。最后,信号量只是从任意数字开始计数,但仅当信号量许可大于 1 时才启动启用等待线程(使用获取)。

一段简单的(非线程)代码也显示了这一点:

@Test
public void testNegativeSemaphore()
{
    Semaphore semaphore = new Semaphore(-2);

    assertEquals(-2, semaphore.availablePermits());
    semaphore.release();
    assertEquals(-1, semaphore.availablePermits());
    semaphore.release();
    assertEquals(0, semaphore.availablePermits());
    semaphore.release();
    assertEquals(1, semaphore.availablePermits());
}
Run Code Online (Sandbox Code Playgroud)

如代码所示,可用许可在每次释放时都会增加,只有当值达到 1 或以上时才允许其他线程获取许可。

请注意,从那时起,通过使用 aqcuire,availablePermits 不能变为负值,因为如果有 0 个许可,那么信号量的全部意义就是等待许可再次可用!