守护线程(Daemon)
Java有两种Thread:“ 守护线程Daemon”与“ 用户线程User”。
任何线程都可以是“ 守护线程Daemon ”或“ 用户线程User ”。他们在几乎每个方面都是相同的,
唯一的区别是用来判断虚拟机何时离开:
用户线程Java虚拟机在它所有非守护线程已经离开后自动离开。
守护线程 守护线程则是用来服务用户线程的,如果没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去。
上面是网上的说法。我觉得它的阐述有些地方不妥。我觉得应该是这样的:
唯一的区别是JVM虚拟机根据是否有用户线程来判断的是否该进程该结束
用户线程: 只要有任何用户线程在运行,该进程就不该结束,否则就应该结束。
守护线程: 守护线程则是用来服务用户线程的。如果程序所在的进程没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去,该线程也就会结束,同时程序所在进程也结束。
setDaemon(boolean on)方法可以方便的设置线程的 Daemon模式, trueDaemon模式falseUser模式
setDaemon(boolean on)方法必须在线程启动之前调用,当线程正在运行时调用会产生异常。
isDaemon方法将测试该线程是否为守护线程。值得一提的是, 当你在一个守护线程中产生了其他线程,
那么这些新产生的线程不用设置Daemon属性,默认是守护线程,当然也可以setDaemon设置为用户线程。

当在用户线程中创建线程时, 它默认是用户线程,也可以setDaemon设置为守护线程
例:我们所熟悉的Java垃圾回收线程就是一个典型的守护线程,当我们的程序中不再有任何运行中的Thread,
程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是Java虚拟机上仅剩的线程时,
Java虚拟机会自动离开。
示例1 :
import java.io.IOException;
/**
 * 守护线程在没有用户线程可服务时自动离开
 */

public class  TestMain4   extends  Thread {
   
    public TestMain4() {
    }
    /**
     * 线程的run方法,它将和其他线程同时运行
     */

     public void   run () {
         for (int i = 1; i <= 100; i++){
             try  {
                Thread.sleep(100);
            }  catch  (InterruptedException ex) {
                ex.printStackTrace();
            }
            System.out.println(i);
        }
    }
   
     public static void   main (String [] args){//这里是个主线程
        TestMain4 test = new TestMain4();
        test.setDaemon(true);
        test.start();
        System.out.println("isDaemon = " + test.isDaemon());
         try  {
             System.in.read() ; // 接受输入,使程序在此停顿,一旦接收到用户输入,main线程结束,守护线程自动结束
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
 
}
注意main(String [] args) 这里是个主线程调用的,它是个用户线程。
实例2
public class   Test  {
 /**
  * @param args
  */

 public static void   main (String[] args) {
        Thread t=new Thread(new MyThread());
        t.setDaemon(true);
        t.start();
        Thread t2=new Thread(new MyThread());
        t2.start();
 }
}
class  MyThread  implements  Runnable
{
 long id=0;
 static long count=0;
 MyThread ()
 {
  id=count;
  count++;
 }
  public void  run()
 { 
   while (true)
  {
    try
   {
    System.out.println("run"+id);
    Thread.sleep(100);
   } catch (InterruptedException e)
   {
    e.printStackTrace();
   }
  }
   
 }
}
注意1 :如果没有t2用户线程进程,t线程在main线程退出后,就没线程可服务了,t线程会结束,
程序所在进程也同时结束了。
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐