Gro Gro - 3 months ago 6x
Java Question

Java threads counter "issue"?

I was trying impact of thread priority and when println in run method stays in comment both threads end in the same time and I don't understand this behavior, can you explain ? Thank you.


public class Main {

public static void main(String[] args) {
Test t1 = new Test("Thread #1");
Test t2 = new Test("Thread #2");



try {
} catch (InterruptedException e) {

System.out.println(t1.thread.getName() + ": " + t1.count);
System.out.println(t2.thread.getName() + ": " + t2.count);

System.out.println("End of main thread.");



public class Test implements Runnable{
public Thread thread;
static boolean stop = false;
int count = 0;

public Test(String name){
thread = new Thread(this, name);

public void run(){

for(int i = 0; i < 10000000 && stop == false; i++){
count = i;
//System.out.println(count + " " + thread.getName());
stop = true;

System.out.println("End of " + thread.getName());

without println with println

End of Thread #1 End of Thread #1
End of Thread #2 End of Thread #2
Thread #1: 9999999 Thread #1: 9999999
Thread #2: 9999999 Thread #2: 3265646
End of main thread. End of main thread.


Your two threads access a shared mutable variable without proper synchronization. In this case, there is no guaranty about when (or whether at all) a thread will learn about a change made by another thread. In your case, the change made by one thread is not noticed by the other at all. Note that while for a primitive data type like boolean, not reading the up to date value is the worst thing that can happen, for non-primitive data types, even worse problems, i.e. inconsistent results could occur.

Inserting a print statement has the side effect of synchronizing the threads, because the PrintStream perform an internal synchronization. Since there is no guaranty that System.out will contain such a synchronizing print stream implementation, this is an implementation specific side-effect.

If you change the declaration of stop to

static volatile boolean stop = false;

the threads will re-read the value from the shared heap in each iteration, reacting immediately on the change, at the cost of reduced overall performance.

Note that there are still no guarantees that this code works as you expect, as there is no guaranty about neither, that the thread priority has any effect nor that threads run in parallel at all. Thread scheduling is implementation and environment dependent behavior. E.g. you might find out that not the thread with the highest priority finishes its loop first, but just the thread that happened to be started first.