在java中的线程setDaemon上的困惑

时间:2011-04-19 08:18:02

标签: java multithreading

根据java,当setDaemon设置为true时

  

它不会阻止JVM   程序结束时退出但是   线程仍在运行。一个   守护程序线程的示例是   垃圾收集。

从以下代码示例中,当setDaemon设置为 true 时,主线程创建的线程停止执行,实际上它应该继续运行。当setDaemon设置为 false 时,即使主线程退出,也会生成i的子线程打印值。 请澄清我的怀疑。

public class DeamonSample implements Runnable
{
      public void run()
      {
            try 
{
System.out.println("T1 started...");

                  for (int i=0;i<1000;i++)
                  {
                        TimeUnit.SECONDS.sleep(1);
                        System.out.print(i+" ");
                  }
            } 
            catch (InterruptedException e) 
            {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            }
            finally
            {
                  System.out.println("T1 ended...");
            }

      }


      /**
      * @param args
      */
      public static void main(String[] args)
      {
            // TODO Auto-generated method stub
            System.out.println("Main Started...");
            System.out.println("Main Thread Type="+Thread.currentThread().isDaemon());
            DeamonSample deamonSample=new DeamonSample();
            Thread t1=new Thread(deamonSample);
            t1.setDaemon(true);
            t1.start();
            System.out.println("T1 Type="+t1.isDaemon());
            System.out.println("Main Thread Type="+Thread.currentThread().isDaemon());
            System.out.println("Main ended...");
      }

}

4 个答案:

答案 0 :(得分:3)

默认情况下,线程不是守护程序线程。如果你使用任何不是守护进程的线程到达main的末尾,那么进程将继续运行。通过调用setDaemon(true),您告诉JVM您的线程不应该在main结束时阻止关闭。

答案 1 :(得分:1)

执行t1.setDaemon(true);时,DeamonSample实例肯定不会停止;你看到的非确定性来自印刷品。在将字符合并为单个流之前,将字符写入线程本地缓冲区。

这里有一些代码可供说明。两个线程轮流递增一个计数器并打印其状态,但是你看到的数字可能非常乱。

import java.util.concurrent.atomic.AtomicInteger;

public class FunnyPrinter extends Thread {
    static AtomicInteger counter = new AtomicInteger(0);

    int parity;

    public FunnyPrinter(int parity) {
        super();
        this.parity = parity;
    }

    public void run() {
        for (;;)
            if (counter.intValue() % 2 == parity)
                System.out.println(counter.incrementAndGet());
    }

    public static void main(String[] args) {
        FunnyPrinter t1 = new FunnyPrinter(0), t2 = new FunnyPrinter(1);
        t1.start(); t2.start();
    }
}

如果您需要确定性,请在阻止结束前在System.outflush上同步。

答案 2 :(得分:0)

主线程在您的守护程序线程打印出所有数字之前终止... 如果你的新线程是damonmon = true,请在启动thread()之后尝试这一行:

...
Thread t1=new Thread(deamonSample);
try{
   t1.join();
}catch(InterruptedException ie){
    ie.printStackTrace();
}
...

你会看到,守护程序线程将结束......(至少,不再是多线程,但该示例仅用于澄清目的)

答案 3 :(得分:0)

  

从以下代码示例中,当setDaemon设置为true时,主线程创建的线程停止执行

这不会发生。再次检查输出。您的输出将包含以下行:

主要开始......
主线程类型=假
T1类型=真
主线程类型=假
主要结束......

  

..实际上它应该继续运行。

作为守护程序线程,它不会。由于所有非守护程序线程(主)都已完成,因此jvm将退出。

  

当setDaemon设置为false时,即使主线程退出,也会生成i的子线程打印值。请澄清我的怀疑。

正确