This example is taken straight from a
Java 2 revision for the programmer exam.
1. class ThreadA {
2. public static void main(
String [] args) {
3. ThreadB b = new ThreadB();
4. b.start();
5.
6. synchronized(b) {
7. try {
8. System.out.println("Waiting for b to complete...");
9. b.wait();
10. } catch (InterruptedException e) {}
11. }
12. System.out.println("Total is: " + b.total);
13. } // end main
14.} // end Class
15.
16.class ThreadB extends
Thread {
17. int total;
18.
19. public void run() {
20. synchronized(this) {
21. for(int i=0;i<100;i++) {
22. total += i;
23. }
24. notify();
25 }
26. }
27.}
Basically the main thread waits for b to do a calculation and prints result. The book explains that when b is started, main continues and gets lock on b, enters its synchronized block. Then wait() on b makes it release the lock and wait until b calls notify to tell it its done calculating. Main can then read the data when selected to run again by JVM, having regotten lock for b. And we're hunky dory.
BUT, what happens it b is lightning fast and its run method is called b4 main get lock on b and calls wait etc (ie b4 main gets to its synch block), which can happen as thread execution is indeterminate. b is in its synchronized block with lock on "this", doing the calculation so main cant enter its synch block.
b completes, and calls notify and exits its synch block. So main can now get lock on b and go into its synch block...but it then calls wait() on b expecting to be notified soon of a calculation completion. But b has exited its synch block earlier and notify() will never be called - is main stuck for ever waiting here???(obviously we could pass a timeout to wait() but that wasnt the case in the code in the book)
cheers
//Tom