-Nikos
This is a race condition. Yielding does *not* guarantee anything about
thread execution order.
Disclaimer: I do not deal with JVM internals. What follows is a
discussion of threads on a standard *NIX system. A sane implementation
of the JVM would simply reuse thread primitives provided by the
operating system, and so the following should apply equally well to
Java.
When a thread yields, it is voluntarily saying, "I have nothing more to
do, but can do more if you don't want to let someone else do something."
The end result is that you are seeing your execution run like:
Main: print("waiting...");
Main: yield
Main: print("waiting...");
Main: yield
Main: print("waiting...");
Main: yield
Main: print("waiting...");
Main: yield
Main: print("waiting...");
Main: yield
Main: print("waiting...");
Main: yield
Main: print("waiting...");
Main: yield
Main: print("waiting...");
Main: yield
Main: print("waiting...");
Main: yield
Main: print("waiting...");
Main: yield
Main: ok = false
ThreadTest: check the value of ok. It's false.
ThreadTest: print("done");
You've created ThreadTest, but it may not be ready to run when the main
thread calls "yield". Thus, the main thread keeps running.
If you need to control the order in which threads interleave (in your
case you want a ping-pong behavior), you need to explicitly enforce this
behavior[1][2][3][4]. Code which does not is broken.
I'd like to see which textbooks/online sources you are using as
statements about thread execution order are generally not specified
without discussion of the sources I cite.
-Robert
1. http://download.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html
2. http://download.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/package-summary.html
3. http://download.oracle.com/javase/6/docs/api/java/util/concurrent/locks/package-summary.html
4. http://en.wikipedia.org/wiki/List_of_Java_keywords
I'd be willing to bet that if you do a test of the number of System.out.println
calls you can do per second, and then divide it by the number of items in each
block, you'll see how many times per second your Java implementation actually
does a yield. I bet it will be right around 100 (even though you likely don't
run Solaris).
This is above and beyond the goals of this course. Do not feel you are under
any pressure to actually do the above experiment. If you wish to do it, please
do it AFTER your final for this course.
Happy Hacking,
Robert
1. OpenJDK 6.0 hotspot/src/os/windows/vm/os_windows.cpp:3840
2. OpenJDK 6.0 hotspot/src/cpu/sparc/vm/globals_sparc.hpp:39
You need to add some form of synchronization to make the program
correct.
-Robert