在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线程模型已经崩溃。