I expected that when each thread executed Thread.yield(), that it would give over execution to another thread to increment _count like this:
In threaded applications that are spinning, predicting the output is extremely hard. You would have to do a lot of work with locks and stuff to get perfect A:1 B:2 C:3 ...
type output.
The problem is that everything is a race condition and unpredictable due to hardware, race-conditions, time-slicing randomness, and other factors. For example, when the first thread starts, it may run for a couple of millis before the next thread starts. There would be no one to yield()
to. Also, even if it yields, maybe you are on a 4 processor box so there is no reason to pause any other threads at all.
Instead, I got output where A would increment _count 100 times, then pass it off to B. Sometimes all three threads would take turns consistently, but sometimes one thread would dominate for several increments.
Right, in general with this spinning loops, you see bursts of output from a single thread as it gets time slices. This is also confused by the fact that System.out.println(...)
is synchronized
which affects the timing as well. If it was not doing a synchronized operation, you would see even more bursty output.
Why doesn't Thread.yield() always yield processing over to another thread?
I very rarely use Thread.yield()
. It is a hint to the scheduler at best and probably is ignored on some architectures. The idea that it "pauses" the thread is very misleading. It may cause the thread to be put back to the end of the run queue but there is no guarantee that there are any threads waiting so it may keep running as if the yield were removed.
See my answer here for more info : unwanted output in multithreading