让我们考虑以下是我们的主题:
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已经启动
作为前三行。
在我的理解中,我没有得到我错过的东西。
答案 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并继续执行。