2012-01-09 37 views
6

我相信主線程不能死在子線程之前。但是有什麼方法可以檢查嗎?我在下面寫了一個簡單的程序。任何人都可以證明它實際上離開理論嗎?可以在主線程死前子線程

class childre extends Thread 
{ 
    public void run() 
    { 
     for(int i=0 ; i<10 ;i++) 
     { 
      System.out.println(" child " + i); 

      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

public class ChildThreadb4main 
{ 

/** 
* @param args 
*/ 
    public static void main(String[] args) 
    { 
    // TODO Auto-generated method stub 

     System.out.println("main"); 

     childre c1 = new childre(); 

     c1.start(); 
     for(int i=0;i<5;i++) 
     { 
      try { 
       Thread.sleep(500); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
     System.out.println(" child thread alive ? " + c1.isAlive()); 
    } 
} 

從詹姆斯的建議後。我嘗試了下面的程序。

public class MainChildDie { 

    public static void main(String ar[]){ 

     final Thread mainThread = Thread.currentThread(); 
     System.out.println("main run "); 

     new Thread(){   

      public void run(){ 

       Thread childThread= Thread.currentThread(); 
       for(int i=0; i<10;i++){ 
        System.out.println("child"+i); 

        try { 
         Thread.sleep(1000); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
       System.out.println("main alive " + mainThread.isAlive()); 
      } 
     }.start();  
    } 
} 
+0

「主」線程沒有什麼特別之處。它只是你看到的第一個(有其他的守護進程線程)如果你製作了所有的「後臺」線程,守護進程線程,主進程退出時程序將退出。否則,程序將繼續運行。 – 2012-01-09 08:09:34

回答

6

http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html

Java虛擬機繼續,直到的 發生以下情況,執行線程:

  1. Runtime類的exit方法已經被調用,經理已允許退出操作發生。

  2. 未守護線程已經死亡,無論是從 調用run方法或通過拋出一個傳播 超越run方法異常返回的所有線程 。

在你的情況,當主線程死亡時,JVM不會退出,因爲你還有所創建的線程中運行,而且他們在默認情況下守護進程,因爲這樣:

新創建的線程最初被標記爲守護線程當且僅當創建它的線程當前標記爲守護線程。 setDaemon方法可用於更改線程是否爲守護進程。

引用:http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setDaemon(boolean)

+3

要添加,沒有父子線程的概念(並且沒有子線程這樣的事情)。每個線程都是獨立的獨立實體。 – Manish 2012-01-09 05:47:05

+0

@ManishSharma - 正確的是,除了守護進程狀態繼續之外,幾乎沒有任何聯繫。 – James 2012-01-09 05:49:19

+0

同意。有沒有辦法檢查線程名稱main的狀態? – randeepsp 2012-01-09 05:57:26

0
Thread.currentThread().getThreadGroup().activeCount() 

將返回當前線程默認的主一個線程組的活動線程

class childre extends Thread 
{ 
    public void run() 
    { 
     for(int i=0 ; i<10 ;i++) 
     { 
      System.out.println(" child " + i); 

      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    System.out.println(Thread.currentThread().getThreadGroup().activeCount()); 
    } 
} 
+0

@詹姆斯和@阿米特現在有點困惑了。如果我添加 --System.out.println(Thread.currentThread()。getThreadGroup()。activeCount()); - 進入MainChildDie類的內部類運行方法,然後返回活動計數爲2,而前面的語句說主要活動假?他們現在意味着什麼? – randeepsp 2012-01-09 09:19:24

+0

@randeepsp,我相信執行main的線程已經完成它的執行,並且線程已經死了。Activecount在某種程度上讓我感到困惑,正如它在thr API中所說的那樣,它應該僅用於onlu的信息目的。我也強制主線程拋出異常,並在它創建的線程仍在後臺運行時終止,並且activeCount仍然是兩個。所以它讓我困惑,並讓我認爲主線程仍然活躍。 – 2012-01-10 12:08:24

0

您可以使用「加入」的方法,以確保主線程等待直到子線程完成。

childre c1 = new childre(); 
c1.start(); 
try { 
c1.join(); 
} catch (InterruptedException exception) { 
    exception.printStackTrace(); 
} 
+0

我不想這樣做。我想實際檢查線程名main是否可以在其它線程產生之前死掉。 – randeepsp 2012-01-10 03:25:59

6

執行代碼時,請執行全線程轉儲並查看所有線程是否處於活動狀態。

class AnotherClass { 
    public static void main(String arrp[]) throws Exception { 
     Thread t = new Thread() { 
      public void run() { 
       while (true) { 
         // do nothing 
       } 
      } 
     }; 
     t.start(); 
      //Sleep for 15 seconds 
     Thread.sleep(15000); 
    } 
} 

編譯並執行它:

$ javac AnotherClass.java 
$ java AnotherClass 

查找過程:

$ ps -ef | grep AnotherClass 

nikunj <<10720>> 10681 2 12:01:02 pts/9  0:04 java AnotherClass 
nikunj 10722 10693 0 12:01:05 pts/6  0:00 grep Another 

採取線程轉儲:

$ kill -3 <<10720>> 

輸出(節選):

"main" prio=10 tid=0x00039330 nid=0x1 waiting on condition [0xffbfe000..0xffbfe2a8] 
    at java.lang.Thread.sleep(Native Method) 
    at AnotherClass.main(AnotherClass.java:12) 

"Thread-0" prio=10 tid=0x00a1b770 nid=0x12 runnable [0xadc7f000..0xadc7f970] 
    at AnotherClass$1.run(AnotherClass.java:7) 

採取另一個線程轉儲(15秒後):

$ kill -3 <<10720>> 

新建輸出(節選):

"Thread-0" prio=10 tid=0x00a1b770 nid=0x12 runnable [0xadc7f000..0xadc7f970] 
    at AnotherClass$1.run(AnotherClass.java:7) 

結論: 主要不見了。

0
class Print implements Runnable 
{ 
    Thread thread, mainThread; 
    Print(Thread t) 
    { 
     mainThread = t; 
     thread = new Thread(this, "Thread"); 
     thread.start(); 
    } 
    @Override 
    public void run() 
    { 
     for(int i = 0; i < 5; i++) 
     { 
      System.out.println(thread.getName() + "\t" + (i+1)); 
      try 
      { 
       Thread.sleep(1000); 
      } 
      catch(InterruptedException ie) 
      { 
       System.out.println("Interrupted Exception " + thread.getName()); 
      } 
      System.out.println("Is main thread alive "+mainThread.isAlive()); 
     } 
    } 
} 
public class ThreadOne 
{ 
    public static void main(String[] args) 
    { 
     Print p1 = new Print(Thread.currentThread()); 
     System.out.println("Main Thread Ends"); 
    } 
} 

上面的代碼會顯示該主線程執行完畢,而newThread催生仍在運行。