Java语句的执行顺序

维品

由于不能保证执行顺序。在下面的程序中,主要方法的执行顺序可以如下?

 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();
  }
}

编辑:想在看到评论后添加一些东西

  1. answerReady可能永远不会成为现实。同意。
  2. 可以更改执行顺序的特殊条件是什么?
  3. 为什么main方法在这里正确同步?
霍尔格

Java语言规范规定了符合标准的JVM可以做什么或不能做什么。

§17.4.5。发生在订单之前

可以通过事前发生关系来排序两个动作如果一个动作发生在另一个动作之前,则第一个动作对第二个动作可见,并在第二个动作之前排序。

如果我们有两个动作xy,我们写hb(x,y)表示x发生在y之前

  • 如果xy是同一线程的动作,并且x按程序顺序位于y之前,则hb(x,y)

由于您对start()的调用join()是同一线程的操作,因此它们相对于程序顺序是有序的。

我认为,很明显,如果没有这种简单的保证,那么即使单线程编程也是不可能的。

这并不意味着代码中没有重新排序。它仅意味着此类优化必须以在执行此代码时保留这些动作可观察到的行为的方式进行。

这里的要点是,尽管主线程将始终如一地执行您要求的操作,但其他线程与这两个操作中的任何一个都不具有先发生后关系,可能不会以相同的方式看到这些操作。对于您而言,在显示了三个线程的情况下,存在几种关系:

§17.4.5的延续

  • 如果hb(x,y)hb(y,z),则hb(x,z)

  • 在启动的线程中的任何操作之前,都会发生start()对线程的调用
  • 线程中的所有操作都会发生-在任何其他线程成功从join()该线程的a返回之前

从中可以得出,代码的所有三个线程在大多数部分上都同意主线程在做什么。

当然,这不会改变以下事实:两个产生的线程不正确地同步(根本不同步),并且t2可能打印该值0而不是42根本不终止。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章