这与这个问题不同。我不能将同步放在 foo 中,因为这会导致线程永远休眠。
我认为您不了解如何wait()
工作notify()
。您无需在线程上等待和通知,而是在同一个对象上进行。当您的代码执行以下操作时:
currentThread.wait(2000);
它实际上导致当前线程等待它自己的Thread
对象。通往notify()
该线程的方式将类似于:
Thread thread = new Thread(myRunnable);
...
thread.notify();
这是一个非常奇怪的模式,很可能不是您想要做的。哪个线程正在运行该foo()
方法并不重要。如果您使用的是线程池,您甚至不会知道哪个线程正在运行它。
如果您希望您的Observer
线程通知等待的线程,foo()
那么它们都需要使用同一个锁对象。就像是:
class MyClass {
...
public synchronized void foo() {
// this is waiting on the current instance of MyClass
wait(2000);
}
}
public class Observer {
...
// to wake up the other thread, we lock the same myClass instance
synchronized (myClass) {
// and notify that object
myClass.notify();
}
}
或者你可以创建一个他们都应该共享的锁对象。
final Object lockObject = new Object();
MyClass c1 = new MyClass(lockObject);
Observer obs = new Observer(lockObject();
...
class MyClass {
private final Object lockObject;
public MyClass(Object lockObject) {
this.lockObject = lockObject;
}
...
public void foo() {
// this is waiting on the current instance of MyClass
synchronized (lockObject) {
lockObject.wait(2000);
}
}
}
...
public class Observer {
private final Object lockObject;
public Observer(Object lockObject) {
this.lockObject = lockObject;
}
public void update(Observable o) {
synchronized (lockObject) {
lockObject.notify();
}
}
}
仅供参考:锁定对象应该几乎总是这样final
,所以它们不能更改它们的引用。你永远不想锁定像 anInteger
或 a那样变化的东西Boolean
。