这是从我的程序中获得的。它打开一个带有按钮的窗口。当我单击按钮时,它应该关闭窗口并唤醒其他线程。但是,它永远不会唤醒另一个线程。底部的“返回主题”从不打印,我也不知道为什么。
public class BrandingGui {
public synchronized void replaceImage() throws IOException{
...
JButton keepButton = new JButton("Keep");
keepButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
frame.dispose();
synchronized(BrandingGui.class) {
//BrandingGui.this.notify();
notifyAll();
}
}
});
...
try {
synchronized(BrandingGui.class) {
this.wait();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("returned to thread");
}
}
看起来您可以正常运行(来自注释),所以很好-但要解决您的OP代码:
当在同步时使用类级别的锁时,您需要在等待/通知时使用类级别的锁-并且不要将实例锁(此)与类级别的锁混合使用:
public class MyClass {
public static void main(String args[]) {
Thread t = new Thread(new Runnable() {
public void run() {
synchronized (MyClass.class) {
MyClass.class.notifyAll();
System.out.println("Awake");
}
}
});
t.start();
synchronized (MyClass.class) {
try {
System.out.println("here");
MyClass.class.wait();
} catch (InterruptedException ie) {
}
}
System.out.println("Done");
}
}
打印:
here
Awake
Done
在您的OP情况下,您使用synchronized
的类级别锁,并且使用this
的notifyall
对象锁:
synchronized(BrandingGui.class) {
notifyAll(); // WRONG - this is the `this` instance lock.
}
因此在这种情况下必须是:
synchronized(BrandingGui.class) {
BrandingGui.class.notifyAll();
}