-
-
Save jeremyheiler/1a5e8961bb132f9cd4f8 to your computer and use it in GitHub Desktop.
public class Main { | |
public static final Object LOCK = new Object(); | |
public static void main(String[] args) throws InterruptedException { | |
new Thread(new A()).start(); | |
new Thread(new B()).start(); | |
} | |
} | |
class A implements Runnable { | |
@Override | |
public void run() { | |
try { | |
long n = System.currentTimeMillis(); | |
synchronized (Main.LOCK) { | |
System.out.println("waiting..."); | |
Main.LOCK.wait(2000); // change this to wait less, more, or indefinitely | |
} | |
System.out.println("waited for " + (System.currentTimeMillis() - n) + "ms"); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
class B implements Runnable { | |
@Override | |
public void run(){ | |
try { | |
System.out.println(0); | |
for (int i = 1; i <= 5; ++i) { | |
Thread.sleep(1000); | |
System.out.println(i); | |
} | |
synchronized (Main.LOCK) { | |
Main.LOCK.notify(); | |
} | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
Basic Wait and Notify Program
What does this program do?
The program starts up two threads, which I'll denote by the class of Runnable
given to them: A and B. Each thread is started as soon as they're created. The Main
class provides a global lock that both threads will synchronize on.
Thread A grabs the monitor for the lock and calls wait()
on it, blocking the thread until another thread obtains the monitor for the lock and notifies it. (This is unclear to me. Calling wait()
must temporarily release the monitor for the lock in order for another thread to obtain it.) Once wait()
returns, the milliseconds it waited for is printed to standard out.
Thread B does some work to pass time. In this case a loop iterates five times, sleeping for a second and printing the current count on each iteration. The count is printed so that it can be compared to how long thread A waits. Once this work is done, the monitor for the lock is obtained and the lock is notified. This will ultimately unblock thread A.
Waiting with a timeout
If thread A calls wait()
with a timeout less than five seconds, it will unblock itself before thread B is given the opportunity to notify it. If the timeout is greater than five seconds, then thread B will end up notifying thread A and unblocking it before the timeout occurs.
Questions
- How does thread B obtain the lock to notify thread A? (Nothing, except the first two printed lines are in a different order. That makes sense, though.)
- Does the lock need to be the same as the one used for wait and notify?
- Does LOCK need to be volatile? (I think it doesn't. It's final and never updated.)
- Does this program change if thread B is started first?
Output: