In an effort to practice my rusty Java, I wanted to try a simple multi-threaded shared data example and I came across something that surprised me.
Basically we have a shared AtomicInteger
counter between three threads that each take turns incrementing and printing the counter.
main
AtomicInteger counter = new AtomicInteger(0);
CounterThread ct1 = new CounterThread(counter, "A");
CounterThread ct2 = new CounterThread(counter, "B");
CounterThread ct3 = new CounterThread(counter, "C");
ct1.start();
ct2.start();
ct3.start();
CounterThread
public class CounterThread extends Thread
{
private AtomicInteger _count;
private String _id;
public CounterThread(AtomicInteger count, String id)
{
_count = count;
_id = id;
}
public void run()
{
while(_count.get() < 1000)
{
System.out.println(_id + ": " + _count.incrementAndGet());
Thread.yield();
}
}
}
I expected that when each thread executed Thread.yield()
, that it would give over execution to another thread to increment _count
like this:
A: 1
B: 2
C: 3
A: 4
...
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.
Why doesn't Thread.yield()
always yield processing over to another thread?