2012-03-11 125 views
7

會在子線程完成執行之前退出主線程?會在子線程完成執行之前退出主線程?

我讀2篇

http://www.cs.mtu.edu/~shene/NSF-3/e-Book/FUNDAMENTALS/thread-management.html

上述文章中

,在「線程終止」對,它在紅州「如果父線程終止,它的所有子線程終止爲好。 「

http://www.roseindia.net/java/thread/overview-of-thread.shtml

上述文章中

,在該頁面狀態下的最後一行「的main()方法執行就可以完成,但該程序將繼續運行,直到所有的線程都完成它的執行。」

我的費用是相互矛盾的。如果我錯了,請高手指正我。

在我的程序中,Main方法調用2個線程的構造函數。在各自線程的構造函數中,我有start()方法。

 TestA A = new TestA("TestA"); 
    TestB B = new TestB("TestB"); 

    public TestA(String name) { 
    System.out.println(name); 
    t = new Thread(this); 
    t.start(); 
} 

我想知道發生了什麼,主線程在子線程完成執行之前終止?如果是這樣,那麼子線程是否會繼續執行?

我試着運行程序,有時候所有的子線程都執行完畢,即使主線程退出。 在2個線程中,我正在處理一些文件。在單獨的testA線程A中,單獨一個文件沒有被處理一些時間。但很多時候,所有的文件都得到處理,我沒有任何問題。

回答

20

Java區分用戶線程和另一種稱爲守護進程線程的線程。這兩種線程之間的區別在於,如果JVM確定應用程序中運行的唯一線程是守護程序線程(即沒有用戶線程),則Java運行時會關閉應用程序。另一方面,如果至少有一個用戶線程處於活動狀態,那麼Java運行時不會終止您的應用程序。

當您的main()方法最初從Java運行時接收控件時,它會在用戶線程的上下文中執行。只要main-method線程或任何其他用戶線程保持活動狀態,您的應用程序將繼續執行。

在你的情況下,線程是用戶線程,因此允許在主線程退出前完成。

我正在處理一些文件。在單獨測試線程A中,僅有1個文件是 未被處理一些時間。但很多次

上述原因可能是線程退出。這可能是文件鎖定,同步問題等

Java Thread API documentation

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

Runtime類的退出方法已被調用,並且管理器已允許安全性 發生退出操作。不是守護線程的所有線程 都已死亡,可以通過調用 返回到run方法,或通過拋出異常傳播 超出run方法。

+0

感謝您的詳細解釋。你已經提到「在你的情況下,線程是用戶線程,因此在主線程退出前允許完成。」在這裏你的意思是「主線程」是Java運行時而不是主方法()的程序。正確? – user1257836 2012-03-11 06:08:03

+0

具有main方法的類和在main方法內部創建的線程都是用戶線程。所有這些線程都是獨立的併發執行。因爲我給了System.out.println(「主要方法的退出」);主要方法的結尾。這會在子線程中的system.out.println()之前打印。這讓我覺得主線程(具有main方法的類)甚至可以在子線程之前退出。這種行爲是否正確和正確? – user1257836 2012-03-11 06:14:53

+0

您能否澄清一下您的文件鎖是什麼意思?提前致謝!! – user1257836 2012-03-11 19:01:52

2

一旦主線程退出,它會帶着孩子。也許通過「完成」第二篇文章只是意味着除了等待孩子之外沒有更多的操作。一旦主線程調用System.exit(0);它已經結束 - 每個人都死亡。

假設你有兩個線程在運行:threadA和threadB。在主要方法。第一個代碼是終止線程的好方法 - 只是衆多方法之一:

threadA.start(); 
threadB.start(); 
final long intercept = 300; 
long startTime = System.currentTimeMillis(); 
while (threadA.isAlive() && mis.isAlive()) { 
    threadA.join(intercept); 
if (System.currentTimeMillis() - startTime > intercept) { 
    threadB.interrupt(); 
    threadA.interrupt(); 
    threadA.join(); 
} 
} 
System.exit(0); 

下面是從內部主殺死所有線程的突然道:

System.exit(0); 
+0

感謝您的回覆。我從來沒有在我的程序中使用過System.exit(0)。「一旦主線程退出,它會帶着這些孩子一起」.am仍然不清楚。具有main方法的程序創建2個線程並完成它。但產生的子線程將繼續,是不正確的? – user1257836 2012-03-11 06:44:46

3

的後臺線程會繼續運行,即使主線程完成。

如果你想MAIN來阻止它們(例如,當MAIN完成時),讓你的MAIN設置一個「keep running」標誌變量(你必須設置爲「volatile」),線程偶爾會看到這個變量。當MAIN想要阻止它們時,MAIN將它設置爲false(變量)或null(對象)。當它爲false或null時,線程必須「返回」。

這實現起來有些複雜,有很多方法,但最簡單的方法是讓你的Runnable成爲一個內部類,這樣你的Runnable就可以輕鬆共享標誌了。

爲了獲得最佳實現,請在Java applets的啓動/停止例程中查找此技術。