我有一个简单的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
,它将被共享,但在这种情况下是什么
请解释一下。
答案 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实例。