简体   繁体   中英

Java Multi-Threading unexpected result

I have a simple Java program with 3 threads, each incrementing and then printing a variable counter . The java code is-

public class test implements Runnable {

    private int counter=0;

    public static void main(String args[]){

        test t=new test();
        Thread t1=new Thread(t,"THREAD 1");
        Thread t2=new Thread(t,"THREAD 2");
        Thread t3=new Thread(t,"THREAD 3");
        t1.start();
        t2.start();
        t3.start();

    }

    public  void run(){

        counter=counter+1;
            System.out.println(Thread.currentThread().getName()+" "+ counter);

    }
}


Understanding that the method run is not synchronized the threads can interleave in any fashion giving any result but the result I get mostly(I've run the program multiple times) is-

THREAD 1 2
THREAD 3 3
THREAD 2 2


I don't understand how come 1 is never printed and even after printing 3 , 2 is again printed(since the most recent value of counter has been set to 3 , as it is printed).

Also, is the variable counter shared among the 3 threads? It will be shared if I make it static but what in this case.
Please explain.

First of all, the instance variable is shared by all the threads, because they are sharing the same instance of the runnable class (in you code there is only one time "new test()").

Why the the value 1 is never printed? This is a little more complex to answer because the order of the instructions is determined by the JVM implementation, the OS and the hardware (in general it is unpredictable). In your case it seems that the print function is called after 2 increment instructions. (if you think that printing is slower than incrementing a variable it take sense).

Finally, value 2 can be printed after value 3, because the println function is not synchronized, this means that also the instruction inside the print function can be interleaved. So in this case the print function on the 2nd thread is called before the function on the 3rd thread, but the first that finished is the 3rd thread.

I hope this can help you.

If you use

    test tOne=new test();
    test tTwo=new test();
    test tThree=new test();
    Thread t1=new Thread(tOne,"THREAD 1");
    Thread t2=new Thread(tTwo,"THREAD 2");
    Thread t3=new Thread(tThree,"THREAD 3");
    t1.start();
    t2.start();
    t3.start();

the output will be something like

THREAD 2 1
THREAD 1 1
THREAD 3 1

counter was shared because you used the same instance of t in all three threads.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM