【发布时间】:2013-11-30 18:31:33
【问题描述】:
一旦调用 notify() 方法,线程会立即放弃监视器,就像在 wait() 中发生的那样。或者调用notify()时,是否会在方法执行完成后释放monitor。
调用 notify() 时线程将进入哪个状态。等待还是阻塞状态?
【问题讨论】:
标签: java multithreading notifications
一旦调用 notify() 方法,线程会立即放弃监视器,就像在 wait() 中发生的那样。或者调用notify()时,是否会在方法执行完成后释放monitor。
调用 notify() 时线程将进入哪个状态。等待还是阻塞状态?
【问题讨论】:
标签: java multithreading notifications
只要在对象上同步,线程就持有对象的监视器。被通知的线程将移动到BLOCKED 状态,并且一旦拥有线程释放它通过离开之前持有监视器的同步块/方法来获取监视器。
例如,如果线程 A 阻塞了对 lock.wait() 的调用,而线程 B 调用了 lock.notify(),则线程 A 将离开 WAITING 状态并进入 BLOCKING 状态**,但线程 A 不会继续执行(即进入RUNNABLE状态)直到线程B离开synchronized块lock。
** 假设没有其他线程在等待
lock,因为不能保证通知线程的顺序,这就是为什么您应该使用notifyAll()作为规则(除非您知道你正在做什么并且有充分的理由不这样做)。
使用代码:
public class ThreadStateTest {
private static final Object lock = new Object();
public static void main(String[] args) {
synchronized (lock) {
new Thread(new RunnableTest()).start();
try {
Thread.sleep(1000);
System.out.println("this will print first");
lock.wait();
System.out.println("this will print third");
} catch (InterruptedException ex) {
}
}
}
private static class RunnableTest implements Runnable {
@Override
public void run() {
try {
synchronized (lock) {
lock.notifyAll();
Thread.sleep(1000);
System.out.println("this will print second");
}
Thread.sleep(1000);
System.out.println("this will print fourth");
} catch (InterruptedException ex) {
}
}
}
}
【讨论】:
在notify() 的情况下,拥有监视器的线程将继续持有监视器。
notify()/notifyAll() 只是通知等待线程他们可以再次选择锁。一旦线程获得监视器,它将退出wait() 方法并继续。
总结一下:一旦锁自然释放(同步块/方法之外),涉及notify()/notifyAll() 的线程将保持RUNNING 状态。
通知的目的只是授权等待线程将来有机会在此可用时立即获得锁。
【讨论】: