2.9 守护线程

2016-07-26 23:25:31 4,423 0

在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)

Daemon的作用是为其他线程的运行提供服务,比如说GC线程。其实User Thread线程和Daemon Thread守护线程本质上来说去没啥区别的,唯一的区别之处就在虚拟机的离开:如果User Thread全部撤离,那么Daemon Thread也就没啥线程好服务的了,所以虚拟机也就退出了。守护线程并非虚拟机内部可以提供,用户也可以自行的设定守护线程,方法:

public final void setDaemon(boolean on);

但是有几点需要注意:

1)、thread.setDaemon(true)必须在thread.start()之前设置,你不能把正在运行的常规线程设置为守护线程,否则会抛出一个IllegalThreadStateException异常。

2)、 在Daemon线程中产生的新线程也是Daemon的

3)、不是所有的应用都适合分配给Daemon线程来进行服务,比如读写操作或者计算逻辑。因为在Daemon Thread还没来的及进行操作时,虚拟机可能已经退出了。The Java Virtual Machine exits when the only threads running are all daemon threads.JVM会在所有执行的线程都是守护线程的时候退出。

例子:

//完成文件输出的守护线程任务
import java.io.*;  
 
class TestRunnable implements Runnable{  
    public void run(){  
               try{  
                  Thread.sleep(1000);//守护线程阻塞1秒后运行  
                  File f=new File("daemon.txt");  
                  FileOutputStream os=new FileOutputStream(f,true);  
                  os.write("daemon".getBytes());  
           }  
               catch(IOException e1){  
          e1.printStackTrace();  
               }  
               catch(InterruptedException e2){  
                  e2.printStackTrace();  
           }  
    }  
}  
public class DaemonThreadDemo{  
    public static void main(String[] args) throws InterruptedException  
    {  
        Runnable tr=new TestRunnable();  
        Thread thread=new Thread(tr);  
        thread.setDaemon(true); //设置守护线程  
        thread.start(); //开始执行分进程  
    }  
}

运行结果:文件daemon.txt中没有"daemon"字符串。

但是如果把thread.setDaemon(true); //设置守护线程注释掉,文件daemon.txt是可以被写入daemon字符串的

JRE判断程序是否执行结束的标准是所有的前台执线程行完毕了,而不管后台线程的状态,因此,在使用后台线程候一定要注意这个问题。 

Daemon线程的实际应用

  以一个web服务器为例,通常有一个调度线程,用来接受用户的请求,然后将请求转发给工作线程来完成。这里工作线程是完成实际工作的,如果所有的工作线程都停止了,调度线程也就没有存在的必要了,因此,调度线程可以设置为守护线程。

上一篇:2.8 线程的状态 下一篇:2.10 ThreadGroup