【问题标题】:Java. The order of threads execution爪哇。线程执行顺序
【发布时间】:2015-09-14 14:54:05
【问题描述】:

我尝试运行书中的示例(Paul Hyde,Java 线程编程)。它说线程的顺序将互换。但我总是得到:10 个“主线程”打印和 10 个“新线程”打印。 更有趣的是:如果我将使用 tt.run 而不是 tt.start,那么结果将反之亦然。也许这本书很老而且示例基于 JDK 1.2 的原因???代码如下:

public class TwoThread extends Thread
{
    public void run()
    {
        for (int i = 0; i < 10; i++)
        {
            System.out.println("New thread");
        }
    }

    public static void main(String[] args)
    {
        TwoThread tt = new TwoThread();
        tt.start();

        for (int i = 0; i < 10; i++)
        {
            System.out.println("Main thread");
        }
    }
}

【问题讨论】:

  • 如果你使用tt.run();,你只有一个线程(它会首先打印“新线程”,因为你首先调用了那个方法)。是 start(); 调用创建并启动了一个实际的新执行线程。
  • 尝试循环到 1000 就知道了。
  • 是的,如果循环更多次,它就可以工作。
  • 你不应该对线程执行顺序做出假设。这就是存在同步原语的原因。

标签: java multithreading


【解决方案1】:

JVM 决定何时将控制权从主线程转移到第二个线程。由于主线程在启动第二个线程后不会执行太多工作,因此 JVM 让它在将控制权转移到第二个线程之前完成其工作是有意义的。

当您使用tt.run() 而不是tt.start() 时,您不会启动第二个线程。您正在主线程中执行run() 方法。因此,您首先会看到 "New thread" 输出。

【讨论】:

  • 还取决于机器是否具有多核处理器以及是否支持超线程
  • JVM 不会在线程之间“转移控制”,而是同时运行它们。即使在单核非 ht 处理器上,一旦两个线程都运行(在任何执行抢占式多任务的操作系统上),排序也是完全随机的。在 Leo 的示例中,排序有点可预测的原因是线程启动时间。
【解决方案2】:

如果我将使用 tt.run 而不是 tt.start 那么结果将是反之亦然。

tt.run 仅在 main 线程中运行,而 tt.start 产生另一个线程。因此结果是预期的。

看到一致性:

对于较小和快速的活动,您可能会偶尔看到一致的结果,但这并不意味着您看到的打印顺序得到保证。将循环迭代增加到更高的数字并查看打印顺序(例如打印多达 10000 次)

【讨论】:

    猜你喜欢
    • 2016-02-16
    • 2013-10-13
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    相关资源
    最近更新 更多