Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behavior of a Java thread associated with System.out [duplicate]

I have a simple TestThreadClientMode class to test a race condition. I tried two attempts:

  1. When I run the following code with System.out.println(count); commented in the second thread, the output was:

OS: Windows 8.1 flag done set true ...

and the second thread was alive forever. Because the second thread never sees change of the done flag which was set true by Main thread.

  1. When I uncommented System.out.println(count); the output was:

    OS: Windows 8.1 0 ... 190785 190786 flag done set true Done! Thread-0 true

And the program stopped after 1 second.

How did System.out.println(count); make the second thread see the change in done?

Code

public class TestThreadClientMode {
    private static boolean done;
    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            public void run() {
                int count = 0;
                while (!done) {
                    count ++;
                    //System.out.println(count);
                }
                System.out.println("Done! " + Thread.currentThread().getName() + "  " + done);
            }
        }).start();
        System.out.println("OS: " + System.getProperty("os.name"));

        Thread.sleep(1000);
        done = true;

        System.out.println("flag done set true ");
    }
}
like image 633
Humoyun Ahmad Avatar asked Aug 30 '15 07:08

Humoyun Ahmad


People also ask

What will happen if multiple threads accessing the same resource?

Multiple threads accessing shared data simultaneously may lead to a timing dependent error known as data race condition. Data races may be hidden in the code without interfering or harming the program execution until the moment when threads are scheduled in a scenario (the condition) that break the program execution.

What problem can occur when two threads share memory?

Thread Interference Error. When multiple threads share the same memory, there is a chance that two or more different threads performing different operations on the same data interleave with each other and create inconsistent data in the memory.

What is Thrad in Java?

A thread in Java is the direction or path that is taken while a program is being executed. Generally, all the programs have at least one thread, known as the main thread, that is provided by the JVM or Java Virtual Machine at the starting of the program's execution.


1 Answers

This is a brilliant example of memory consistency errors. Simply put, the variable is updated but the first thread does not always see the variable change. This issue can be solved by making done variable volatile by declaring it like so:

private static volatile boolean done;

In this case, changes to the variable are visible to all threads and the program always terminates after one second.

Update: It appears that using System.out.println does indeed solve the memory consistency issue - this is because the print function makes use of an underlying stream, which implements synchronization. Synchronization establishes a happens-before relationship as described in the tutorial I linked, which has the same effect as the volatile variable. (Details from this answer. Also credit to @Chris K for pointing out the side effect of the stream operation.)

like image 60
Parker Hoyes Avatar answered Sep 30 '22 16:09

Parker Hoyes