java主線程結束和子線程結束之間的關系


最近在和同事討論 java 主線程和子線程之間的關系,自己也到網上搜索了下,發現各種答案都有,有些還是互相矛盾的。經過測試自己得出以下幾個結論,跟大家分享下,如果有錯誤,歡迎大牛指正,幫助我這只小菜鳥。廢話不多說,直接上結論:

(一)Main 線程是個非守護線程,不能設置成守護線程。
這是因為,main 線程是由 java 虛擬機在啟動的時候創建的。main 方法開始執行的時候,主線程已經創建好並在運行了。對於運行中的線程,調用 Thread.setDaemon() 會拋出異常 Exception in thread "main" java.lang.IllegalThreadStateException。測試代碼如下:

public class MainTest
{
public static void main(String[] args)
{
System.out.println(" parent thread begin ");
Thread.currentThread().setDaemon(true);
}
}
(二)Main 線程結束,其他線程一樣可以正常運行。
主線程,只是個普通的非守護線程,用來啟動應用程序,不能設置成守護線程;除此之外,它跟其他非守護線程沒有什么不同。主線程執行結束,其他線程一樣可以正常執行。代碼如下:

public class ParentTest
{

public static void main(String[] args)
{
    System.out.println("parent thread begin ");
    
    ChildThread t1 = new ChildThread("thread1");
    ChildThread t2 = new ChildThread("thread2");
    t1.start();
    t2.start();

    System.out.println("parent thread over ");
}

}

class ChildThread extends Thread
{
private String name = null;

public ChildThread(String name)
{
    this.name = name;
}

@Override
public void run()
{
    System.out.println(this.name + "--child thead begin");

    try
    {
        Thread.sleep(500);
    }
    catch (InterruptedException e)
    {
        System.out.println(e);
    }

    System.out.println(this.name + "--child thead over");
}

}

--程序運行結果如下:
parent thread begin
parent thread over
thread2--child thead begin
thread1--child thead begin
thread2--child thead over
thread1--child thead over
這樣其實是很合理的,按照操作系統的理論,進程是資源分配的基本單位,線程是 CPU 調度的基本單位。對於 CPU 來說,其實並不存在 java 的主線程和子線程之分,都只是個普通的線程。進程的資源是線程共享的,只要進程還在,線程就可以正常執行,換句話說線程是強依賴於進程的。也就是說,線程其實並不存在互相依賴的關系,一個線程的死亡從理論上來說,不會對其他線程有什么影響。

(三)Main 線程結束,其他線程也可以立刻結束,當且僅當這些子線程都是守護線程。
java 虛擬機 (相當於進程) 退出的時機是:虛擬機中所有存活的線程都是守護線程。只要還有存活的非守護線程虛擬機就不會退出,而是等待非守護線程執行完畢;反之,如果虛擬機中的線程都是守護線程,那么不管這些線程的死活 java 虛擬機都會退出。測試代碼如下:

public class ParentTest
{

public static void main(String[] args)
{
    System.out.println("parent thread begin ");
    
    ChildThread t1 = new ChildThread("thread1");
    ChildThread t2 = new ChildThread("thread2");
    t1.setDaemon(true);
    t2.setDaemon(true);
    
    t1.start();
    t2.start();

    System.out.println("parent thread over ");
}

}
class ChildThread extends Thread
{
private String name = null;
public ChildThread(String name)
{
this.name = name;
}
@Override
public void run()
{
System.out.println(this.name + "--child thead begin");
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
System.out.println(e);
}
System.out.println(this.name + "--child thead over");
}
}

執行結果如下:
parent thread begin
parent thread over
thread1--child thead begin
thread2--child thead begin

在這種情況下,的確主線程退出,子線程就立刻結束了,但是這是屬於 JVM 的底層實現機制,並不是說主線程和子線程之間存在依賴關系。
我的博客參考了 http://bbs.csdn.net/topics/360195074 這篇文章中大家的一些交流,碰撞出真知,大家的智慧是無窮的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM