Dan*_*den 10 java semaphore java.util.concurrent
一个看似简单的问题:我有一个java.util.concurrent.Semaphore
,我希望获得许可证使用acquire()
.
如果线程被中断,acquire()
则指定该方法抛出InterruptedException
:
如果当前线程:
- 在进入此方法时设置其中断状态; 要么
- 在等待许可证时被打断,
然后抛出InterruptedException并清除当前线程的中断状态.
但是,使用可能抛出的方法的通常模式InterruptedException
是在循环中调用它们,因为线程可能受到虚假唤醒的影响,这些唤醒看起来与被中断相同.例如,文档Object.wait(long)
说:
线程也可以在没有被通知,中断或超时的情况下唤醒,即所谓的虚假唤醒.虽然这在实践中很少发生,但应用程序必须通过测试应该导致线程被唤醒的条件来防范它,并且如果条件不满足则继续等待.换句话说,等待应始终在循环中进行.
所以问题是,是否Semaphore.acquire()
受到同样的虚假唤醒?合乎逻辑的答案是"不",但我找不到任何证据,实际上证据似乎指向了另一个方向.
查看源代码Semaphore
,它似乎将实际的获取委托给a AbstractQueuedSynchronizer
,根据其来源代表LockSupport.park()
.
明确提到虚假唤醒的文档LockSupport.park()
,但实现AbstractQueuedSynchronizer.doAcquireInterruptably()
似乎只是检查Thread.interrupted()
然后抛出InterruptedException
.
所以,除非我遗漏了某些东西(这是非常可能的),否则看起来可能Semaphore.acquire()
会抛出InterruptedException
虚假的东西?
那是对的吗?更重要的是,我能做些什么吗?我可以使用Semaphore.acquireUninterruptably()
,但我不想要一个不间断的等待,只是一个不会被虚假中断的.还有其他选择吗?
它是"虚假唤醒"而非"虚假中断":"线程也可以在没有被通知,中断或超时的情况下唤醒,即所谓的虚假唤醒." 在虚假唤醒期间没有抛出InterruptedException.正如你在评论中所说:线程醒来但是没有设置中断的标志.
归档时间: |
|
查看次数: |
2717 次 |
最近记录: |