简体   繁体   English

信号量虚假唤醒

[英]Spurious wakeup with Semaphore

I have a doubt: let's assume I have an object of class Semaphore called sem and that a thread tries to acquire a permission doing sem.acquire() and that there are not, so the thread is suspended. 我有一个疑问:假设我有一个名为sem Semaphore类对象,并且一个线程尝试通过sem.acquire()获得许可,而没有,则该线程被挂起。 Now if the thread is awakened by a spurious wakeup, what happend? 现在,如果线程被虚假唤醒唤醒,会发生什么? Should I insert the sem.acquire() in a sort of loop? 我应该在某种循环中插入sem.acquire()吗?

Only the very basic Object.wait() method is subjected to spurious wakeups (actually only the Unsafe.park() method, but there is no way to access that without hacks), all more sophisticated tools deal with that internally. 只有非常基本的Object.wait()方法才会受到虚假唤醒(实际上只有Unsafe.park()方法,但是如果没有黑客手段,则无法访问它),所有更复杂的工具都会在内部进行处理。

If you have a look at the actual code of Semaphore.acquireUninterruptibly() you'll find the following construct (hidden in AbstractQueuedSynchronizer.doAcquireShared() ): 如果查看Semaphore.acquireUninterruptibly()的实际代码,则会发现以下构造(隐藏在AbstractQueuedSynchronizer.doAcquireShared() ):

for (;;) {
    // ... try aquire, else:
    if (shouldParkAfterFailedAcquire(p, node) &&
        parkAndCheckInterrupt())
        interrupted = true;
}

The for(;;) loop is basically a while(true) loop, so even though parkAndCheckInterrupt() can spuriously wake up, the loop will ensure that this will just cause another failed tryAquire run, then it will be put back to sleep. for(;;)循环基本上是一个while(true)循环,因此即使parkAndCheckInterrupt()可能会虚假地唤醒,该循环也将确保这只会导致另一个tryAquire运行失败,然后将其重新休眠。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM