主线程运行顺序

时间:2016-05-31 11:55:53

标签: java multithreading

让我们考虑以下是我们的主题:

public class HeavyWorkRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println("Doing heavy processing - START "+Thread.currentThread().getName());
        try {
            doDBProcessing();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Doing heavy processing - END "+Thread.currentThread().getName());
    }

    private void doDBProcessing() throws InterruptedException {
     //   TODO
    }
}

主要方法:

public class ThreadRunExample {
     public static void main(String[] args){

            Thread t1 = new Thread(new HeavyWorkRunnable(), "t1");
            Thread t2 = new Thread(new HeavyWorkRunnable(), "t2");
            System.out.println("Starting Runnable threads");

            t1.start();
            t2.start();
            System.out.println("Doing main heavy processing - START "+Thread.currentThread().getName());
            System.out.println("Runnable Threads has been started");
        }
}

现在输出在不同的运行时间是不同的。例如:

输出1
启动Runnable线程
进行主要重处理 - START主要
进行繁重的处理 - START t1
进行繁重的处理 - START t2
进行繁重的处理 - 结束t2
Runnable Threads已经启动了 进行繁重的处理 - 结束t1

输出2
启动Runnable线程
进行主要重处理 - START主要
Runnable Threads已经启动了 进行繁重的处理 - START t1
进行繁重的处理 - 结束t1
进行繁重的处理 - START t2
进行繁重的处理 - 结束t2

根据我对线程的理解:
1.一次只能运行一个线程 2.如果没有设置优先级,系统会随机选择线程。

因此,系统应该完成“主要”的任务。线程,然后运行t1或t2。如果是,则输出应始终包含:
启动Runnable线程
进行主要重处理 - START主要
Runnable Threads已经启动
作为前三行。 在我的理解中,我没有得到我错过的东西。

3 个答案:

答案 0 :(得分:0)

事情是:操作系统及其处理队列之间存在差异。 这是一个冗长的话题,但长话短说: 当三个线程在系统队列上时,操作系统让其中一个线程只运行一小部分时间(称为量子),然后将其推送到队列以让其他线程运行,依此类推,产生多任务处理的错觉在单处理器 - 单核架构中。为此,由于种种原因,每次执行都会有所不同。

如果您真的想深入了解这个主题,请从这里开始link

答案 1 :(得分:0)

在一个处理器中,只有一个线程可以在给定时间运行,这是事实。但Java虚拟机包含一个称为线程调度程序的组件。该组件确实选择哪个线程进入处理器以及哪个线程进入。

启动线程时,它将进入runnable状态。当线程调度程序有一个用于处理时间的槽时,它将选择所有 runnable 线程中的一个(如果它们都具有相同的优先级,则随机选择)。在Thread Scheduler中断处理并将线程放回 runnable 状态之前,所选择的状态进入running状态几毫秒。

线程因此无法保证在离开处理器之前完成其工作。

当您遇到线程时,您应该考虑所有已启动的线程可以在同一时间同时运行,因此无保证排序。

您可能想要检查的是如何在其他线程上使用Object.wait()方法创建线程等待,但这远远超出了这个答案。

如果你需要深入研究Java中的线程,你应该考虑一个特定的培训或谷歌的在线资源,因为这根本不明显。

答案 2 :(得分:0)

首先让我清楚你的理解 只有一个线程可以在给定时间运行,但它仅适用于单核处理器而不适用于多核。

现在Main方法只不过是内部线程。现在,线程调度和时间切片取决于操作系统。因此,当您运行程序时Main方法仍然在Time Slice中,因此执行 System.out.println("Doing main heavy processing - START "+Thread.currentThread().getName()); 语句而不是语句。

如果要更改输出,则必须从操作系统的时间片中删除主线程。

所以,在t2.start()之后;使用Thread.sleep(1000),你可以检查你的t1或t2线程是否会获得Scheduler并继续执行。