Java 多线程意外结果



我有一个简单的Java程序,有3个线程,每个线程递增然后打印一个变量counter。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);
    }
}


了解方法run不同步,线程可以以任何方式交错给出任何结果,但我得到的结果(我已经多次运行该程序)是-

THREAD 1 2
THREAD 3 3
THREAD 2 2


我不明白为什么1永远不会打印,甚至在打印3之后,2再次打印(因为counter的最新值已设置为 3,因为它被打印)。

另外,变量counter 3 个线程之间共享吗?如果我把它static,它将被共享,但在这种情况下呢。
请解释一下。

首先,实例变量由所有线程共享,因为它们共享可运行类的同一实例(在您的代码中只有一次"new test()")。

为什么从不打印值 1?这个问题回答起来有点复杂,因为指令的顺序是由JVM实现,操作系统和硬件决定的(通常它是不可预测的)。在您的情况下,似乎在 2 个增量指令后调用打印函数。(如果您认为打印比递增变量慢,这是有意义的)。

最后,值 2 可以在值 3 之后打印,因为 println 函数不同步,这意味着打印函数内部的指令也可以交错。因此,在这种情况下,第 2 个线程上的 print 函数在第 3 个线程上的函数之前调用,但第一个完成的是第 3 个线程。

我希望这能帮助你。

如果你使用

    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();

输出将类似于

THREAD 2 1
THREAD 1 1
THREAD 3 1

counter共享是因为您在所有三个线程中都使用了相同的 t 实例。

最新更新