簡體   English   中英

為什么一個線程比Java中的main方法更長?

[英]Why does a thread outlive the main method in Java?

我在教自己Java線程,我注意到一些讓我困惑的東西。 我創建了一個名為engine的類,它實現了Runnable run方法只打印“Hello World”,睡眠一秒,然后重復。

在我的主要方法中,我有:

public static void main(String[] args) {
    Thread thread = new Thread(engine);
    thread.start();
    System.out.println("Done.");
}

正如我所料,我看到“Hello World”和“Done”。 快速打印,意味着主要方法已經到了最后,但我沒想到的是,即使在主要結束之后,我開始運行的線程仍在運行。

為什么程序在主要退出后仍繼續執行? 我會想到,當主要退出時,進程將終止並且所有線程都將被強制清除。 這是否意味着必須為每個Java程序顯式連接/終止每個線程?

因為這是它的工作原理。 調用System.exit()時,或者當最后一個非守護程序線程停止運行時,程序退出。

這是有道理的。 例如,如果沒有這個規則,每個只生成GUI的Java程序都必須無限地等待()以避免程序立即退出。

如果希望程序在main方法完成時退出,請考慮制作線程守護進程。 但是要注意這樣一個事實,當主要完成時,守護程序線程將被中止。
您可以像這樣創建一個守護進程:

Thread t = new Thread(...);
t.setDaemon(true);

所有非守護程序線程都是用戶線程。 那些線程正在阻止jvm關閉。

用戶線程繼續獨立於其父線程的生命周期運行,即創建者線程。 因此,您必須通過在main線程終止之前調用Thread.join來顯式連接線程。

ThreadJavadoc

當Java虛擬機啟動時,通常會有一個非守護程序線程(通常調用某個指定類的名為main的方法)。 Java虛擬機繼續執行線程,直到發生以下任一情況:

  1. 已調用類Runtime的exit方法,並且安全管理器已允許執行退出操作。

  2. 所有非守護程序線程的線程都已死亡,無論是通過從run方法調用返回還是拋出傳播超出run方法的異常。

如果你想JVM,即使一個線程終止t運行時,你應該讓線程t守護線程

t.setDaemon(true);

有兩種類型的線程,用戶和守護進程。 當沒有更多用戶線程時,該進程終止。 主線程始終是用戶線程。 您啟動的線程也是一個用戶線程,因此只要它運行就會使進程保持活動狀態。

在啟動它之前在線程上調用setDaemon(true)將使您的進程在main()函數返回后立即終止(或多或少)。

Java語言規范部分12.8表明:

12.8。 程序退出

程序會終止其所有活動,並在發生以下兩種情況之一時退出:

所有不是守護程序線程的線程都會終止。

某些線程調用類Runtime或類System的exit方法,安全管理器不禁止退出操作。

這意味着主線程完成是不夠的。

如果你希望它在主線程結束時退出,你需要使用Thread#setDaemon使新線程成為守護進程,或者按照你最初的建議使用Thread#join

主線程也是正在創建的用戶線程,其生命周期類似於任何其他用戶線程。
除非您將線程設置為守護程序線程,否則其他用戶線程不會出於任何原因依賴於主線程。 一旦主線程完成其工作,它就會結束(它既不會結束其他用戶線程也不會結束進程,因為其他用戶線程正在運行)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM