Java Multi-Threading意外结果

时间:2016-07-15 10:04:15

标签: java multithreading java-threads

我有一个简单的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的最新值已设置为{ {1}},因为它被打印)。

另外,变量3是否在3个线程中共享?如果我将其设为counter,它将被共享,但在这种情况下是什么 请解释一下。

2 个答案:

答案 0 :(得分:2)

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

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

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

我希望这可以帮到你。

答案 1 :(得分:1)

如果您使用

    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实例。