http://blog.sina.com.cn/s/blog_605f5b4f0100udin.html

Java有两种Thread:守护线程Daemon和用户线程User。

任何线程都可以是守护线程Daemon或者用户线程User,他们几乎每个方面都是相同的,唯一的区别是判断虚拟机何时离开:

用户线程:Java虚拟机在它所有非守护线程已经离开后自动离开。

守护线程:守护线程是用来服务用户线程的,如果没有其他用户线程在运行,那么就没有可服务对象,也没有理由继续下去。

 

setDaemon(boolean on)方法可以方便地设置线程Daemon模式,true为Daemon模式,false为User模式。该方法必须在线程启动之前调用,当线程运行时调用时会产生异常。

 

当你在一个守护线程中产生了其他线程,那么这些新产生的线程不用设置Daemon属性,都将是守护线程。用户线程与此相同。

 

使用下面的程序来说明:

import static java.lang.System.out;
import static java.lang.System.in;

import java.io.IOException;
public class TestMain4 extends Thread{
 public TestMain4(){
 
 }
 
 public void run(){
  for(int i=1;i<=50;i++){
   try{
    Thread.sleep(100);
    out.println("this is in TestMain4");
   }catch(InterruptedException ex){
    ex.printStackTrace();
   }
   out.println("TestMain4:"+i);
  }
 }
 
 public static void main(String[] args){
  TestMain4 test=new TestMain4();
  TestMain5 test1=new TestMain4.TestMain5();
  test.setDaemon(false);//用户线程,必须结束后才能退出JVM
  test.start();
 
  test1.setDaemon(true);//守护线程,不需要结束
  test1.start();
  System.out.println("isDaemon="+test.isDaemon());
  System.out.println("isDaemon="+test1.isDaemon());
 

  try {
  out.print("the input is: "+in.read());
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 }
 
 static class TestMain5 extends Thread{
  public TestMain5(){
  
  }
 
  public void run(){
   for(int i=1;i<=50;i++){
    try{
     Thread.sleep(1000);
     out.println("this is in TestMain5");
    }catch(InterruptedException ex){
     ex.printStackTrace();
    }
    out.println("TestMain5:"+i);
   }
  }
 }
}

结果:

isDaemon=false
isDaemon=true
this is in TestMain4
TestMain4:1
this is in TestMain4
TestMain4:2
this is in TestMain4
TestMain4:3
this is in TestMain4
TestMain4:4
this is in TestMain4
TestMain4:5
this is in TestMain4
TestMain4:6
this is in TestMain4
TestMain4:7
this is in TestMain4
TestMain4:8
this is in TestMain4
TestMain4:9
this is in TestMain5
TestMain5:1
this is in TestMain4
TestMain4:10
this is in TestMain4
TestMain4:11
this is in TestMain4
TestMain4:12
this is in TestMain4
TestMain4:13
this is in TestMain4
TestMain4:14
this is in TestMain4
TestMain4:15
this is in TestMain4
TestMain4:16
this is in TestMain4
TestMain4:17
this is in TestMain4
TestMain4:18
this is in TestMain4
TestMain4:19
this is in TestMain5
TestMain5:2
this is in TestMain4
TestMain4:20
this is in TestMain4
TestMain4:21
5this is in TestMain4
TestMain4:22
this is in TestMain4
TestMain4:23
this is in TestMain4
TestMain4:24
this is in TestMain4
TestMain4:25
this is in TestMain4
TestMain4:26
this is in TestMain4
TestMain4:27

this is in TestMain4
TestMain4:28
the input is: 53this is in TestMain4
TestMain4:29
this is in TestMain5
TestMain5:3
this is in TestMain4
TestMain4:30
this is in TestMain4
TestMain4:31
this is in TestMain4
TestMain4:32
this is in TestMain4
TestMain4:33
this is in TestMain4
TestMain4:34
this is in TestMain4
TestMain4:35
this is in TestMain4
TestMain4:36
this is in TestMain4
TestMain4:37
this is in TestMain4
TestMain4:38
this is in TestMain4
TestMain4:39
this is in TestMain5
TestMain5:4
this is in TestMain4
TestMain4:40
this is in TestMain4
TestMain4:41
this is in TestMain4
TestMain4:42
this is in TestMain4
TestMain4:43
this is in TestMain4
TestMain4:44
6this is in TestMain4
TestMain4:45
this is in TestMain4
TestMain4:46
this is in TestMain4
TestMain4:47

this is in TestMain4
TestMain4:48
this is in TestMain4
TestMain4:49
this is in TestMain5
TestMain5:5
this is in TestMain4
TestMain4:50

可以看到JVM退出时,非守护线程即用户线程TestMain4已经执行完毕,而TestMain5是守护线程,只执行了5次就退出了。如果将TestMain5改成非守护线程,那么TestMain4执行完毕后必须等TestMain5执行完毕才能退出JVM。

 

public static void main 是在一个非守护线程中运行的,但是JVM中并不一定只有这个非守护线程,可以在程序中启动多个非守护线程,JVM同样也会等待它们的退出。 所以并非运行main方法的线程退出就一定退出JVM。


Logo

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

更多推荐