医生说
acquire()
处于独占模式:
// Acquires in exclusive mode, ignoring interrupts.
public final void acquire(int arg) {
if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
没有任何限制,它首先调用
tryAcquire(arg)
。
如果一个线程已经持有同步(已获取但未释放),其他线程也可以不受任何限制地调用 tryAcquire(arg) 并且可能会成功获取。
简单来说,我的意思是,为什么 AbstractQueuedSynchronizer 在调用之前不检查线程是否已保持同步
tryAcquire(arg)
。
虽然用户可以实现
tryAcquire(arg)
,但确保第二个tryAcquire(arg)
不能成功。但我认为这是AQS的责任。
想了想,我同意在acquire()中实现exclusive不好,最好在tryAcquire()中实现exclusive。
很难对“为什么”问题做出明确的答案,但这里有一个用例,我很高兴事情就是这样:项目反应器和虚拟线程。
当访问资源的工作项在一个操作系统线程上运行并且该线程上没有其他工作项时,将资源分配给线程是有意义的。
对于具有 m:n 线程概念的编程模型来说,情况可能并非如此 - 您的工作项可能会切换到另一个线程,而不同的工作项将在您的线程上运行。
因此,例如使用 spring-webflux (构建在 Reactor 之上),您可以与
Semaphore
等同步(它是在 AbstractQueuedSynchronizer
的帮助下实现的,但不能与内置 synchronized
同步)关键字。