我有以下代码,我打算在打印出“Main:pre-sync”之后死锁。但看起来synchronized
并没有达到我的预期。这里发生了什么?
import java.util.*;
public class deadtest {
public static class waiter implements Runnable {
Object obj;
public waiter(Object obj) {
this.obj = obj;
}
public void run() {
System.err.println("Thead: pre-sync");
synchronized(obj) {
System.err.println("Thead: pre-wait");
try {
obj.wait();
} catch (Exception e) {
}
System.err.println("Thead: post-wait");
}
System.err.println("Thead: post-sync");
}
}
public static void main(String args[]) {
Object obj = new Object();
System.err.println("Main: pre-spawn");
Thread waiterThread = new Thread(new waiter(obj));
waiterThread.start();
try {
Thread.sleep(1000);
} catch (Exception e) {
}
System.err.println("Main: pre-sync");
synchronized(obj) {
System.err.println("Main: pre-notify");
obj.notify();
System.err.println("Main: post-notify");
}
System.err.println("Main: post-sync");
try {
waiterThread.join();
} catch (Exception e) {
}
}
}
由于两个线程在创建的对象上同步,我希望线程实际上相互阻塞。目前,代码很高兴地通知其他线程,加入和退出。
答案 0 :(得分:4)
当你在一个对象上wait()
时,该线程释放对象上的锁,以允许其他人获取锁和notify()
等待线程。请参阅javadoc for Object.wait()
。
当前线程必须拥有此对象的监视器。 线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。 线程然后等待,直到它可以重新获得监视器的所有权并继续执行。
答案 1 :(得分:4)
在监视器上调用.wait()
实际上会释放同步锁,以便其他线程可以锁定到同一监视器并发送通知。
您的行为完全正常:“服务员”锁定监视器,然后在等待通知时释放锁定。 1秒钟后,主线程锁定监视器,发送通知,解锁监视器,唤醒服务员完成其操作。