public class B {
private int x;
public void foo() {
int current = x;
x = current + 1;
}
public void go() {
for(int i = 0; i < 5; i++) {
new Thread() {
public void run() {
foo();
System.out.print(x + ", ");
}
}.start();
}
}
public static void main(String args[]){
B bb = new B();
bb.go();
}
}
本准则来自SCJP。我对理解逻辑感到困惑。我的理解是,这个代码有5个线程(1个主线程和1个循环)但我不知道我是如何得到这个输出:3,5,3,4,3,
虽然我知道输出因机器不同而有所不同,但我想了解hows的线程是否在洗牌之间
此致
答案 0 :(得分:1)
我不确定执行顺序的所有Java规则是什么;但我认为在没有同步的情况下,操作可以按任何顺序执行,“操作”不必是整个语句。假设您将代码分解为四个操作:阅读x
并设置current
(在foo
中);分配给x
(foo
);阅读x
(在run
中),进入一些临时的;将x
(来自临时)的值与逗号连接并打印出来。这是一个可能导致您看到的输出的顺序,但我相信遵循Java规则,每个线程中的操作以正确的顺序执行。请注意,每个线程都有自己的值current
(在foo()
中),但x
由所有线程共享。
Thread 1: Read x into current (0)
Thread 1: Set x to 1
Thread 2: Read x into current (1)
Thread 2: Set x to 2
Thread 3: Read x into current (2)
Thread 3: Set x to 3
Thread 1: Read x into temporary (3)
Thread 2: Read x into temporary (3)
Thread 3: Read x into temporary (3)
Thread 4: Read x into current (3)
Thread 4: Set x to 4
Thread 4: Read x into temporary (4)
Thread 5: Read x into temporary (4)
Thread 5: Set x to 5
Thread 5: Read x into temporary (5)
Thread 3: Print x (3)
Thread 4: Print x (4)
Thread 2: Print x (3)
Thread 5: Print x (5)
Thread 1: Print x (3)
当然,这不是产生该输出的唯一可能的顺序。
答案 1 :(得分:0)
5个线程共享属于“bb”对象的x变量。因此,当执行其run方法时,执行可以在任何时候从1个线程切换到另一个。因此,当他们打印时,其他一些线程可能比其他线程更进一步,或者根本没有开始......
在运行的每一行添加带有线程ID的打印件。 foo方法,看看他们如何交织。
答案 2 :(得分:-1)
有6个主题,主要是1个,循环有5个