【问题标题】:Order of thread execution in JavaJava中的线程执行顺序
【发布时间】:2016-07-06 21:33:07
【问题描述】:

我对 java 中的线程执行顺序有疑问。 这个例子

  public class Thr implements Runnable {
    String string = "Yes ";
    public void run(){
      this.string = "No ";
    }
    public static void main (String args[]){
      Thr t = new Thr();
      new Thread(t).start();
      for(int i = 0; i < 10; i++)
          System.out.println(t.string);
    } 
  }

给出输出:

Yes 
No 
No 
No 
No 
No 
No 
No 
No 
No 

我把这个话题加红了 Java. The order of threads execution 我很困惑为什么在第一次通过for循环后将字符串更改为no。 我坚持认为,由于主线程没有大的工作要做,主线程将首先执行,输出将是

Yes 
Yes 
Yes 
Yes 
Yes 
Yes 
Yes 
Yes 
Yes
No

当我在 run 方法中放置一些 print 而不是 this.string = "No" 然后,从 run 方法打印最后打印。

【问题讨论】:

  • 是的,但是我认为,由于主线程没有太多工作,所以会执行第一个for循环,然后执行new Thread(t).start(); ,所以它会是,最后,不是
  • 但是当我把,例如,在运行 System.out.println("Thread") 和 main System.out.println("Main") 的 for 循环中,程序打印字符串 Thread最后
  • 线程彼此独立运行。没有明确的顺序,它很可能会发生你所期望的。但是,如果您依赖它,那纯属运气。
  • 在竞争问题(指令执行的相对顺序)之上,此代码表现出可见性问题(何时写入string 变量对主线程可见)。所以,是的,真的任何事情都可能发生在这里。

标签: java multithreading


【解决方案1】:

我想我知道发生了什么。问题是,这个线程、主线程和新线程(t)都在并行执行。这是一种抽奖,因为它们都请求处理器时间,所以,当主线程开始执行时,它需要执行的所有代码,主线程都会花费处理器时间,它只会先打印是,然后是新的Thread(t) 获取他的处理器时间,将“是”更改为否,并完成执行,然后主线程再次继续执行。我做了一个小测试,在

public class Thr implements Runnable {
  String string = "Yes ";
  public void run(){
    this.string = "No ";
  }
  public static void main (String args[]){
  Thr t = new Thr();
  Thread tr = new Thread(t);
  tr.start();
  for(int i = 0; i < 10; i++)
      System.out.println(t.string + tr.isAlive());
  } 
}

输出是

Yes true
No false
No false
No false
No false
No false
No false
No false
No false
No false

【讨论】:

    【解决方案2】:

    使用线程时要确定一件事,即使您调用此方法,您也无法预测线程何时启动:

    new Thread(t).start();
    

    当您调用它时,线程进入“准备开始运行或可运行状态”的状态,然后线程调度程序可以获取线程并将其置于运行状态,如果他想要的话,这有点复杂但当你有一堆线程时,你无法预测会发生什么,有时如果你启动两个线程,最后一个线程会先运行。有关该主题的更多理解,请参阅this

    【讨论】:

    • 我知道这一点,但我只是很困惑,为什么如果 this.string = "no" 在运行中它只在第一次迭代后改变,并且对于所有其他操作,它首先执行主线程一段时间......即使我进行了 5000 次迭代,它仍然会在第一次迭代后从 yes 变为 no。 JVM 执行得更快,因为它不包含很多工作要做吗?
    • 你唯一能知道的是它没有指定会发生什么。编写任何依赖于以特定顺序执行的线程或一个线程在另一个线程之前执行的代码,而没有特定的同步调用,保证在某些时候会失败。不这样做,你就不用担心了。
    • 我很痛苦地意识到这一点:D,但这是我的 Java 考试示例,所以我无法避免:)
    • 是的,玩线程很酷,尝试打印值,然后稍等片刻,看看会发生什么:)
    猜你喜欢
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多