在Java中有两类线程:
用户线程 (User Thread) 和 守护线程 (Daemon Thread)。
守护线程
是指在程序运行的时候在后台提供一种通用服务的线程,并不属于程序中不可或缺的部分
当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程
用户线程和守护线程区别:
唯一的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。
将线程转换为守护线程
通过调用Thread对象的setDaemon(true)方法来实现。在使用守护线程时需要注意一下几点:
必须在start()方法之前设置
thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。
在Daemon线程中产生的新线程也是Daemon的
守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断
编写实例
- 编写DeamonThread类实现往文件中写入数据的功能
- 在主线程中将DeamonThread设置为守护线程 并且使用键盘输入模拟阻塞状态
- 当从键盘输入后从阻塞状态进入运行状态 主线程执行结束 守护线程也结束
DeamonThread :
package thread.demo3;
import java.io.*;
/**
* 守护线程DeamonThread
* Created by heqianqian on 2017/4/15.
*/
public class DeamonThread implements Runnable {
private int count = 0;
@Override
public void run() {
System.out.println("Deamon Thread Running....");
File file = new File("Base/file/deamon/file.txt");
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file, true);
while (count < 999) {
outputStream.write(("word:"+count+"\r\n").getBytes());
System.out.println(Thread.currentThread().getName()+" write word "+count++);
Thread.sleep(1000);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (outputStream!=null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Deamon Thread Over!");
}
}
Main:
package thread.demo3;
import java.util.Scanner;
/**
* Main
* Created by heqianqian on 2017/4/15.
*/
public class Main {
public static void main(String[] args) {
System.out.println("Main Thread Running....");
DeamonThread deamonThread = new DeamonThread();
Thread thread = new Thread(deamonThread);
thread.setDaemon(true);//设置为守护线程 且必须在start前调用
thread.start();
Scanner scanner = new Scanner(System.in);
scanner.next();//模拟阻塞
System.out.println("Main Thread Over!");
}
}
运行结果:
file.txt文件内容:
使用jstack生成线程快照
运行程序后 打开任务管理器 找到当前程序的PID
打开CMD 输入
jstack -l pid
可以看到快照结果
我们可以分析一下
C: