2012-01-09 39 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催生仍在运行。