在Java中,为什么一个线程在从.wait()唤醒后必须竞争资源?
例如,在这个经典的消费者生产者代码片段中:在Java中,为什么一个线程在从.wait()唤醒后必须竞争资源?,java,multithreading,locking,synchronized,producer-consumer,Java,Multithreading,Locking,Synchronized,Producer Consumer,例如,在这个经典的消费者生产者代码片段中: synchronized (this) { while (queue.isEmpty()) { this.wait(); } queue.remove(); this.notifyAll(); } 生产者通知的.wait()使用者线程将被唤醒,然后与等待同步(this)的其他使用者线程竞争资源。这会导致竞争状况。但是为什么不简单地让.wait()使用者保留资源,直到它存在已同步的块?这是一个天真的问题。。感谢这些评论,我想我现
synchronized (this) {
while (queue.isEmpty()) {
this.wait();
}
queue.remove();
this.notifyAll();
}
生产者通知的
.wait()
使用者线程将被唤醒,然后与等待同步(this)
的其他使用者线程竞争资源。这会导致竞争状况。但是为什么不简单地让.wait()
使用者保留资源,直到它存在已同步的
块?这是一个天真的问题。。感谢这些评论,我想我现在明白了设计背后的逻辑:
.wait()
线程在等待时不能只持有锁,因为这样生产者就无法写入队列.wait()
线程唤醒时,为什么不能保证它获得锁?因为由于原因#1,.wait()
线程必须在开始等待之前放弃资源。同时,其他使用者线程可以到达.wait()
阶段。由于有许多线程在等待,谁应该获得资源?Java选择对所有线程一视同仁,更不用说等待时间了您是否在谈论
wait()
消费者之间的公平性?那么,如果另一个消费者也需要资源,您如何决定谁获得资源?我是说,你的解决方案是什么?在多个消费者试图获得资源的情况下,谁来决定选择哪个消费者?这不是竞争条件。这是不公平的,可能会导致饥饿。您通常需要做出决定,以获得公平的日程安排或最后一点性能。Java选择了后者。@k5\u。。。并提供了ReentrantLock
来支持前者。@AKSW我的意思是,让.wait()
线程在睡眠时保持锁。这样,在同步的块中只有一个线程可以执行。Java没有选择公平。您不能保证首先开始等待的线程将首先获得锁。@JBNizet捕获得不好。误解了公平性的含义。不幸的是,Java方法避免了公平性和确定性行为。在Java中,无法保证特定的等待线程将访问共享资源。平均而言,这是可行的,但行为的平均值并不是行为的保证。由于缺乏线程访问共享资源的保证,显然Java线程模型已经崩溃。