为何给定Java线程代码输出始终为One Two Main?线程执行逻辑解析
为什么这段Java线程代码的输出始终是"One Two Main"?
首先得揪出这段代码里最容易被误解的点:Thread.sleep()是静态方法!不管你用哪个Thread实例(比如t1、t2)去调用它,实际都是让当前正在执行这段代码的线程(也就是main线程)进入休眠状态,而不是你调用的那个线程。
我们一步一步拆解代码的执行流程,就能明白为什么输出顺序固定:
首先,
main线程创建了Runnable实例,接着创建t1线程并调用t1.start():- 调用
start()后,t1线程进入就绪状态,等待CPU调度。因为t1的run()方法只是简单打印线程名,耗时几乎可以忽略,所以CPU很快会调度t1执行,输出One,然后t1线程就结束了。
- 调用
接下来执行
t1.sleep(2000):- 这里不是让
t1休眠!而是main线程自己休眠2000毫秒(2秒)。在这2秒里,t1早就执行完消失了,main线程啥也不干,就等着时间到。
- 这里不是让
2秒后
main线程醒来,创建t2线程并调用t2.start():- 和
t1一样,t2进入就绪状态后很快被CPU调度,执行run()输出Two,然后t2线程结束。
- 和
然后执行
t2.sleep(1000):- 还是
main线程自己休眠1000毫秒(1秒),t2同样早就执行完了。
- 还是
1秒后
main线程醒来,执行System.out.print("Main "),输出最后一段内容。
至于为什么t1总是最先启动而不是其他顺序?因为t1.start()之后,main线程立刻调用了sleep(),这时候main线程主动让出CPU资源,而t1已经处于就绪状态,CPU会优先调度t1执行。等t1执行完,main还在休眠,所以t1的输出肯定是第一个。
最后提个小建议:以后调用sleep()的时候,直接写Thread.sleep(2000)就好,不要用线程实例调用,这样能避免这种误解,代码可读性也更高。
内容的提问来源于stack exchange,提问作者Abhilash
相关产品推荐
相关产品推荐

