首页 > 代码库 > 关于java多线程中守护线程的理解

关于java多线程中守护线程的理解

 

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

守护线程并非只有虚拟机内部提供,用户在编写程序时也可以自己设置守护线程。下面的方法就是用来设置守护线程的。 

1 Thread daemonTread = new Thread();  
2    
3 // 设定 daemonThread 为 守护线程,default false(非守护线程)  
4 daemonThread.setDaemon(true);  
5    
6 // 验证当前线程是否为守护线程,返回 true 则为守护线程  
7 daemonThread.isDaemon();  

有几点需要注意: 
(1) thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。
(2) 在Daemon线程中产生的新线程也是Daemon的。 
(3) 不要认为所有的应用都可以分配给Daemon来进行服务,比如读写操作或者计算逻辑。 

针对第三点,下面看个例子

 1 public class MyThread extends Thread {
 2     @Override
 3     public void run() {
 4         try {
 5             Thread.sleep(1000);// 守护线程阻塞1秒后运行 
 6             FileOutputStream fis = new FileOutputStream(new File("e://test.txt"));
 7             fis.write("test a nonrm cmd".getBytes());
 8         } catch (FileNotFoundException e) {
 9             e.printStackTrace();
10         } catch (IOException e) {
11             e.printStackTrace();
12         } catch (InterruptedException e) {
13             e.printStackTrace();
14         }
15     }
16 }
1 public class Run {
2     public static void main(String[] args) throws InterruptedException {
3         MyThread myThread = new MyThread();
4         myThread.setDaemon(true);
5         myThread.start();
6     }
7 }

可以看到当不把该线程设置为守护线程时,文件能正常写入

技术分享

但是设置为守护线程时,内容就写不进去了

技术分享

我们知道静态变量是ClassLoader级别的,如果Web应用程序停止,这些静态变量也会从JVM中清除。但是线程则是JVM级别的,如果你在Web 应用中启动一个线程,这个线程的生命周期并不会和Web应用程序保持同步。也就是说,即使你停止了Web应用,这个线程依旧是活跃的正是因为这个很隐晦的问题,所以很多有经验的开发者不太赞成在Web应用中私自启动线程。

如果我们手工使用JDK Timer(Quartz的Scheduler),在Web容器启动时启动Timer,当Web容器关闭时,除非你手工关闭这个Timer,否则Timer中的任务还会继续运行

 

关于java多线程中守护线程的理解