主线程可以在子线程之前死掉

时间:2012-01-09 05:36:40

标签: java multithreading

我相信主线程在子线程之前不能死掉。但有什么方法可以检查吗?我在下面写了一个简单的程序。任何人都可以证明它几乎把理论放在一边吗?

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();      
    }
}

5 个答案:

答案 0 :(得分:7)

当代码正在执行时,进行全线程转储并查看所有线程都处于活动状态。

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)

<强>结论: 主要消失了。

答案 1 :(得分:6)

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

  

Java虚拟机继续执行线程,直到其中任何一个   发生以下情况:

     
      
  1. 已调用类Runtime的exit方法和安全性   经理允许退出操作。

  2.   
  3. 所有主题   那些不是守护程序的线程已经死亡,要么从返回   调用run方法或抛出传播的异常   超越运行方法。

  4.   

在你的情况下,当主线程死掉时,JVM不会退出,因为你仍然有创建的线程在运行,并且默认情况下它们是守护进程,因为:

  

当且仅当创建它的线程当前标记为守护程序线程时,新创建的线程最初被标记为守护程序线程。 setDaemon方法可用于更改线程是否为守护进程。

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

答案 2 :(得分: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());
    }
}

答案 3 :(得分:0)

您可以使用'join'方法确保主线程等待子线程完成。

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

答案 4 :(得分: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仍然在运行。