简体   繁体   English

Java多线程意外结果

[英]Java Multi-Threading unexpected result

I have a simple Java program with 3 threads, each incrementing and then printing a variable counter . 我有一个带有3个线程的简单Java程序,每个线程递增1,然后打印一个变量counter The java code is- Java代码是-

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- 理解方法run是不同步的,线程可以以任何方式进行交织,从而给出任何结果,但是我得到的大部分结果(我已多次运行程序)是-

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). 我不明白为什么永远不会打印1 ,甚至在打印3之后也要再次打印2 (因为在打印时counter最新值已设置为3 )。

Also, is the variable counter shared among the 3 threads? 另外,变量counter在3个线程之间共享? It will be shared if I make it static but what in this case. 如果我将其设为static ,它将被共享,但在这种情况下会共享。
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()"). 首先,所有线程共享实例变量,因为它们共享可运行类的相同实例(在您的代码中,只有一次“ new test()”)。

Why the the value 1 is never printed? 为什么值1从不打印? 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). 由于指令的顺序是由JVM实现,操作系统和硬件决定的(通常是不可预测的),因此回答起来会有些复杂。 In your case it seems that the print function is called after 2 increment instructions. 在您的情况下,似乎在2个增量指令之后调用了print函数。 (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. 最后,由于println函数不同步,因此可以在值3之后打印值2,这意味着也可以交错打印函数中的指令。 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. 因此,在这种情况下,第2个线程上的print函数在第3个线程上的函数之前被调用,但是第一个完成的函数是第3个线程。

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. 因为您在所有三个线程中使用了相同的t实例,所以共享了counter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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