首页 文章

java中线程setDeaemon的混乱

提问于
浏览
0

根据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

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

  • 3

    执行 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 上进行同步 .

  • 0

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

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

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

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

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

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

    正确

  • 1

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

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

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

相关问题