Thread之守护线程
守护线程
java有两种Thread: 守护线程“DaemonThread” 与 用户线程“UserThread”;
守护线程是一种“在后台提供通用性支持”的线程,让并不属于程序本体;
任何线程都可以是DaemonThread或者UserThread,他们唯一的区别就是判断虚拟机何时离开;
用户线程和守护线程的区别:
用户线程:java虚拟机在它所非守护线程已经离开后自动离开;
守护线程:守护线程是用来服务用户线程的,如果没有其他用户线程在运行,就没有服务对象了,就会消亡结束;
守护线程并非虚拟机内部可以提供,用户也可以自行的设定守护线程,方法:public final void setDaemon(boolean on) ;但是有几点需要
守护线程限制注意:
1)thread.setDaemon(true);必须在thread.start();之前设置,否则会跑出异常:IllegalThreadStateExpection(非法线程状态异常)
1)限制就是潜藏告诉信息:你不能把正在运行的常规线程设置为守护线程。以为set要放在启动之前,启动后的就不能设置了 (这点与守护进程有着明显的区别,守护进程是创建后,让进程摆脱原会话的控制+让进程摆脱原进程组的控制+让进程摆脱原控制终端的控制;所以说寄托于虚拟机的语言机制跟系统级语言有着本质上面的区别)
2)在Daemon线程中产生的新线程也是daemon的
2)当你在守护线程中产生了其他线程,那么这些新产生的线程不用设置Daemon属性,都将是守护线程,用户线程也同理。
(这一点又是有着本质的区别了:守护进程fork()出来的子进程不再是守护进程,尽管它把父进程的进程相关信息复制过去了,但是子进程的父进程不是init进程,所谓的守护进程本质上说就是“父进程挂掉,init收养,然后文件0,1,2都是/dev/null,当前目录到/”)
3)不是所有的应用都可以分配给Daemon线程来进行服务,比如说IO读写操作或者计算逻辑(因为很可能在DaemonThread还没来得及进行操作时,虚拟机可能已经退出了)
守护线程的应用:
例:我们所熟悉的Java垃圾回收线程就是一个典型的守护线程,当我们的程序中不再有任何运行中的Thread,程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是Java虚拟机上仅剩的线程时,Java虚拟机会自动离开。
daemon Thread实际应用在那里呢?举个例子,web服务器中的Servlet,容器启动时后台初始化一个服务线程,即调度线程,负责处理http请求,然后每个请求过来调度线程从线程池中取出一个工作者线程来处理该请求,从而实现并发控制的目的。