我有一个简单的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 实例。