简体   繁体   English

在notify()之后做很多工作会导致wait()变得忙碌等待吗?

[英]doing lot of work after notify() will cause wait() become busy wait?

if i have the below piece of code 如果我有下面的代码

synchronized (this)
{
    System.out.println("Waiting for return key.");
    scanner.nextLine();
    System.out.println("Return key pressed.");
    notify();
    Thread.sleep(5000);
}

After notify , I am calling sleep which means, I have notified the waiting thread but not relinquished the lock, what happens now.. After notifying the waiting thread would have been woken up but not able to acquire the lock, so from here on-wards, is it a busy wait? notify之后,我正在调用sleep,这意味着,我已通知等待线程但没有放弃锁,现在会发生什么。.通知等待线程将被唤醒但无法获取锁,因此从这里开始-病房,忙吗? since we are not going to call notify again. 因为我们不会再打电话notify

Same question goes with notify and notifyall , after one thread woken and acquired lock, is that all other thread waiting becomes busy wait? 相同的问题与notifynotifyall ,在一个线程唤醒并获得锁定之后,所有其他线程等待都变成繁忙等待吗?

wait()并不忙于等待,但是一旦得到通知,它就会“以通常的方式与其他线程竞争在对象上进行同步的权利”

A call to notify wakes up one thread that is currently waiting on the object's condition queue which then tries to reaquire the lock which is still held by the calling thread at that point of time. 调用notify唤醒当前正在对象的条件队列上等待的一个线程,然后该线程尝试重新获取该时间点调用线程仍保留的锁。 So the situation is comparable to a thread that wants to enter a synchronized block that is currently executed by another thread. 因此,这种情况与想要输入另一个线程当前正在执行的synchronized块的线程可比。 The thread is not doing a busy-wait , it is just blocked until it can aquire the lock. 线程没有执行忙等待 ,它只是被阻塞,直到可以获取锁为止。

When the thread that called notify releases its lock, the other thread can be unblocked and continue to work. 当调用notify的线程释放其锁时,另一个线程可以被解除阻塞并继续工作。

The same is true for notifyAll , but it wakes up all threads that are waiting on the object's condition queue. 对于notifyAll也是如此,但是它唤醒了对象条件队列中所有正在等待的线程。 As only one of them can acquire the lock, the others stay blocked until they get the lock - one after the other. 由于他们中只有一个可以获取锁,因此其他人将一直处于阻塞状态,直到他们获得锁为止-一个接一个。 This and because thread-awaking signals may happen spontaneous it is required to always call wait within a conditional loop: 这是因为线程唤醒信号可能自发发生,因此需要始终在条件循环内调用wait

synchronized (lockObject) {
    // ...
    while (!condition) {
        lockObject.wait();
    }
    // object is now in desired state
}

See also: Java Concurrency in Practice , Chapter 14.2 另请参阅: Java并发实践 ,第14.2章

A thread can wait on an object only when IT OWNS the object's monitor. 仅当线程拥有对象的监视器时,线程才能在对象上等待。 Once the first thread notifies, the second thread wakes up but doesn't do anything. 一旦第一个线程通知,第二个线程将唤醒,但不执行任何操作。 The only thing that happens here is that "The thread will be removed from the list of threads waiting on the object . It is left to the OS to schedule its execution. The OS might choose NOT to execute it for sometime. The thread doesn't busy-wait. It will just be in the set of threads which are waiting to be scheduled. 唯一发生的事情是“该线程将从等待对象的线程列表中删除。该线程留给OS安排其执行。OS可能会选择暂时不执行它。线程不会t busy-wait。它只是在等待调度的线程集中。

As @Holger points out, any thread which calls wait() releases the lock on the object. 正如@Holger指出的那样,任何调用wait()的线程都会释放对象上的锁。 Once it is notified, it has to "compete" and reacquire the lock on the object. 收到通知后,它必须“竞争”并重新获取对象上的锁。 Reacquiring of lock doesn't happen when notify() is called by the thread which holds the lock. 当持有锁的线程调用notify()时,不会重新获得锁。 It happens when that thread exits its synchronized block. 当该线程退出其同步块时,就会发生这种情况。

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

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