由于执行顺序无法保证。在下面的程序中,main方法的执行顺序可以像下面这样吗?
t2.start();
t2.join();
t1.start();
t1.join();
程序是:
public class Puzzle {
static boolean answerReady = false;
static int answer = 0;
static Thread t1 =
new Thread() {
public void run() {
answer = 42;
answerReady = true;
}
};
static Thread t2 =
new Thread() {
public void run() {
while (!answerReady) Thread.sleep(100);
System.out.println("The meaning of life is: " + answer);
}
};
public static void main(String[] args) throws InterruptedException {
t1.start();
t2.start();
t1.join();
t2.join();
}
}
编辑:看到评论后想添加一些内容
- answerReady 可能永远不会成为现实。同意。
- 可以更改执行顺序的特殊条件是什么?
- 为什么 main 方法在这里正确同步?
最佳答案
Java 语言规范规定了符合标准的 JVM 可以做什么或不可以做什么。参见
§17.4.5. Happens-before Order
Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second.
If we have two actions x and y, we write hb(x, y) to indicate that x happens-before y.
- If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
- …
由于 start()
和 join()
的调用是同一线程的操作,因此它们是根据程序顺序排序的。
我认为,很明显,如果不存在这种简单的保证,即使是单线程编程也是不可能的。
这并不意味着代码中没有重新排序。它仅意味着此类优化必须以在执行此代码时保留这些操作的可观察行为的方式进行。
这里的要点是,虽然主线程将始终执行您告诉它执行的操作,但与这些操作中的任何一个没有发生之前关系的其他线程可能看不到这些操作以同样的方式。在您的例子中,显示了三个线程,存在多种关系:
§17.4.5 的延续
- …
- If hb(x, y) and hb(y, z), then hb(x, z).
…
- A call to
start()
on a thread happens-before any actions in the started thread.- All actions in a thread happen-before any other thread successfully returns from a
join()
on that thread.
由此,您可以得出代码的所有三个线程都同意主线程在大多数部分所做的事情。
当然,这不会改变两个生成的线程不正确(根本没有)同步的事实,并且 t2
可能会打印值 0
而不是 42
或根本不终止。
关于java - java语句的执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38225392/