Java Semaphor不支持提供的参数吗?

时间:2018-12-05 13:09:26

标签: java multithreading concurrency semaphore

当我使用带有1个参数的信号量时。 然后将其释放两次,它将可用许可证增加到2个,但理想情况下,我已经提到我想要1个锁。现在,由于我有2个可用许可证,因此两个线程可以获得该锁,这将破坏参数的目的。

Semaphor lock = new Semaphor(1);
lock.release();
lock.release();

lock.acquire(); // thread1
lock.acquire(); //thread2

为什么会这样?

3 个答案:

答案 0 :(得分:1)

  

为什么会这样?

doc提到了它:

  

以这种方式使用时,二进制信号量具有属性(不同于   许多Lock实现),则“锁”可以由   所有者以外的线程(因为信号量没有   所有权)。 这在某些特殊情况下很有用,例如   死锁恢复


您可以使用wrapper类来跟踪初始许可证。但是通常,不应该在线程release锁定之前调用aquire,所以它应该不会成为问题。

答案 1 :(得分:0)

release()

来自Oracle doc:释放许可证,将可用许可证数量增加一个。如果有任何线程试图获取许可,则选择一个线程并授予刚刚释放的许可。出于线程调度目的而启用了该线程。

不要求释放许可证的线程必须已经通过调用invoke()获得了该许可证。通过应用程序中的编程约定,可以正确使用信号量。

答案 2 :(得分:0)

  

现在,由于我有2个可用许可证,因此两个线程可以获取违反参数目的的锁。

这不会违反Semaphore的目的。 Semaphore的目的是实现here中所述的计数信号量抽象。

  

为什么Semaphore不尊重所提供的论点?

它确实很荣幸。但是论点并没有限制许可的数量。相反,它表示最初可以无阻碍获取的许可证数量。

  

为什么会这样?

因为(在Java设计人员看来)计数信号量 的行为方式。

标准Semaphore类没有限制许可数量的方法。如果要使用锁(或二进制信号量),则应使用Lock类...


  

但是在多线程应用程序中,发布和获取可能会不同步,并且最终会调用两次发布。

是的。那将是应用程序中的错误。

现在……如果您想检测到这一点,则可以扩展Semaphore类并覆盖acquirerelease方法,以检查许可数量是否在规定的范围内。 (如果检查失败,则可以引发未经检查的异常。或者,您可以静默忽略该请求……尽管这听起来是个坏主意。)