gpt4 book ai didi

java - Java 信号量的确定性如何保证?

转载 作者:行者123 更新时间:2023-12-02 12:49:57 25 4
gpt4 key购买 nike

(Oracle) javadoc对于 Semaphore.release()包括:

If any threads are trying to acquire a permit, then one is selected and given the permit that was just released.


这是一个艰难的 promise 吗?这意味着如果线程 A 在 acquire() 中等待和线程 B 这样做:
sem.release()
sem.acquire()
然后 release()应该将控制权交给 A 并且 B 将在 acquire() 中被阻止.如果只有这两个线程可以持有信号量并且 doc 语句在形式上为真,那么这是一个完全确定的过程:之后,A 将获得许可,B 将被阻塞。
但这不是真的,或者至少在我看来确实如此。我没有在这里为 SSCCE 烦恼,因为我真的只是在寻找确认:
比赛条件适用:即使线程 A 正在等待许可,但当它被释放时,它可以立即被线程 B 重新获取,而线程 A 仍然被阻塞。
如果这有什么不同的话,这些是“公平”的信号量,我实际上在 kotlin 工作。

最佳答案

在对问题 Slaw 的评论中指出 the documentation 中的其他内容:

When fairness is set true, the semaphore guarantees that threads invoking any of the acquire methods are selected to obtain permits in the order in which their invocation of those methods was processed (first-in-first-out; FIFO). Note that FIFO ordering necessarily applies to specific internal points of execution within these methods. So, it is possible for one thread to invoke acquire before another, but reach the ordering point after the other, and similarly upon return from the method.


这里的重点是 acquire()是一个有开始和结束的可中断函数。在其异常期间的某个时刻,调用线程在公平队列中确保了一个位置,但是当它与同时访问同一函数的另一个线程相关时仍然是不确定的。将此点称为 X 并考虑两个线程,其中一个持有信号量。在某个时候,另一个线程调用:
   sem.acquire()
无法保证调度程序不会将 acquire() 内的线程搁置一旁。在到达 X 点之前。 如果所有者线程然后这样做(这可能是,例如,旨在作为某种同步检查点或屏障控制):
   sem.release()
sem.acquire()
它可以简单地释放和获取信号量而不被另一个线程获取,即使该线程已经进入 acquire。 . Thread.sleep()的注入(inject)或 yield()通话之间可能经常会起作用,但这不是保证。要创建具有该保证的检查点,您需要两个锁/信号量进行交换:
  • 所有者线程持有semA .
  • 客户端线程可以带semB然后等待semA .
  • 楼主可以放semA然后等待semB ,如果另一个线程真的在等待 semA持有semB , 将阻止和保证 semA现在可以由客户获取。
  • 当客户端完成后,它会释放 semB ,然后 semA .
  • 当所有者从等待 semB 中释放时,可以获取semA并发布semB .

  • 如果这些被正确封装,这个机制是坚如磐石的。

    关于java - Java 信号量的确定性如何保证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62503346/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com