That's is NOT the same as this question. I cannot put synchronized in foo because that would cause the thread to sleep forever.
I don't think you are understanding how wait()
and notify()
work. You do not wait and notify on the threads, you do it on the same object. When your code does:
currentThread.wait(2000);
it is actually causing the current thread to wait on it's own Thread
object. The way to notify()
that thread would then be something like:
Thread thread = new Thread(myRunnable);
...
thread.notify();
This is a very strange pattern and is most likely not what you want to do. It shouldn't matter which thread is running the foo()
method. If you were using a thread-pool you wouldn't even know which thread was running it.
If you want your Observer
thread to notify the thread waiting in foo()
then they both need to be working with the same lock object. Something like:
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();
}
}
Or you could create a lock object that they both should share.
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();
}
}
}
FYI: Lock objects should almost always be final
so they can't change their reference. You never want to lock on something that changes like an Integer
or a Boolean
.