后台线程也叫守护线程。可以在调用start开启线程之前,调用setDaemon(true)把线程设置为守护线程。
注意事项:
1、main线程不能设置为守护线程,切记。
2、设置守护线程必须要调用start()方法之前。
开启守护线程的基本用法
class SimpleDaemons5 implements Runnable {
private int count = 10;
@Override
public void run() {
while (count-- < 0) {
PrintUtils.print(Thread.currentThread() + " " + this);
}
}
}
public class ThreadTest5 {
public static void main(String[] args) {
Thread daemon = new Thread(new SimpleDaemons5());
//设置守护线程
daemon.setDaemon(true);
}
}
守护线程和非守护线程之间的联系
main线程和非守护线程之间的联系
main线程结束,非守护线程。我们看看下面的实例以及打印的结果就可以很清晰的看出来。
class SimpleDaemons5 implements Runnable {
@Override
public void run() {
try {
while (true) {
TimeUnit.MILLISECONDS.sleep(170);
PrintUtils.print(Thread.currentThread() + " " + this);
}
} catch (InterruptedException e) {
PrintUtils.print("Sleep interrupterd");
}
}
}
public class ThreadTest5 {
public static void main(String[] args) {
PrintUtils.print("main 线程开始");
Thread daemon = new Thread(new SimpleDaemons5());
daemon.start();
try {
TimeUnit.MILLISECONDS.sleep(175);
} catch (InterruptedException e) {
e.printStackTrace();
}
PrintUtils.print("main 线程 结束");
/**
*
*
* 输出:
* main 线程开始
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* main 线程 结束
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* ......
*
*/
}
}
mian线程休息175毫秒之后停止,子线程休息170毫米之后停止,所以子线程有时间能打印结果。
由输出结果可以看出,当mian线程结束之后,非守护线程依然可以运行。
非守护线程和守护线程之间的联系
mian线程+一个守护线程的情况
main线程也是非守护线程。我们首先看只有一个main线程和一个守护线程的情况
class SimpleDaemons5 implements Runnable {
@Override
public void run() {
try {
while (true) {
TimeUnit.MILLISECONDS.sleep(20);
PrintUtils.print(Thread.currentThread() + " " + this);
}
} catch (InterruptedException e) {
PrintUtils.print("Sleep interrupterd");
}
}
}
public class ThreadTest5 {
public static void main(String[] args) {
PrintUtils.print("main 线程开始");
Thread daemon = new Thread(new SimpleDaemons5());
//设置守护线程
daemon.setDaemon(true);
daemon.start();
try {
TimeUnit.MILLISECONDS.sleep(175);
} catch (InterruptedException e) {
e.printStackTrace();
}
PrintUtils.print("main 线程 结束");
/**
*
*
* 输出:
* main 线程开始
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons5@1d296048
* main 线程 结束
*
* Process finished with exit code 0
*
*/
}
}
示例分析:
mian线程休息175毫秒之后停止,子线程休息20毫米之后停止,所以子线程有时间能打印结果。
由输出可以看出,当main线程结束时,守护线程也结束了。
多个非守护线程+一个守护线程
我们再来看看有两个非守护线程(其中包括一个mian线程),一个守护线程的情况
class SimpleDaemons implements Runnable {
@Override
public void run() {
try {
while (true) {
TimeUnit.MILLISECONDS.sleep(40);
PrintUtils.print("守护正在运行" + Thread.currentThread() + " " + this);
}
} catch (InterruptedException e) {
PrintUtils.print("Sleep interrupterd");
}
}
}
class SimpleDaemons2 implements Runnable {
private int count = 7;
@Override
public void run() {
try {
while (count-- > 0) {
TimeUnit.MILLISECONDS.sleep(40);
PrintUtils.print("非守护正在运行 count: " + count);
}
} catch (InterruptedException e) {
PrintUtils.print("Sleep interrupterd");
}
}
}
public class ThreadTest4 {
public static void main(String[] args) {
PrintUtils.print("main 线程开始");
//开启守护线程
Thread daemon = new Thread(new SimpleDaemons());
//设置为后台线程
daemon.setDaemon(true);
daemon.start();
//开启非守护线程
Thread daemon2 = new Thread(new SimpleDaemons2());
daemon2.start();
//主线程休息175秒之后结束
try {
TimeUnit.MILLISECONDS.sleep(175);
} catch (InterruptedException e) {
e.printStackTrace();
}
PrintUtils.print("main 线程 结束");
/**
* 输出:
*
* main 线程开始
* 非守护正在运行 count: 6
* 守护正在运行Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons@11f3ef5e
* 非守护正在运行 count: 5
* 守护正在运行Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons@11f3ef5e
* 守护正在运行Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons@11f3ef5e
* 非守护正在运行 count: 4
* 非守护正在运行 count: 3
* 守护正在运行Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons@11f3ef5e
* main 线程 结束
* 非守护正在运行 count: 2
* 守护正在运行Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons@11f3ef5e
* 守护正在运行Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons@11f3ef5e
* 非守护正在运行 count: 1
* 守护正在运行Thread[Thread-0,5,main] annotation_demo.thread_demo.SimpleDaemons@11f3ef5e
* 非守护正在运行 count: 0
*
* Process finished with exit code 0
*
*/
}
}
由输出结果可以看到,main线程结束了,非守护线程没有结束,守护线程也没有结束;
当非守护线程结束之后,守护线程就结束了。
综合上面的两个例子,我们可以得出结论:
只要有任何一个非守护线程(main也是非守护线程)没有结束,守护线程就不会结束;
如果全部的非守护线程都结束,守护线程就结束。
可以简单理解为:没有被守护者了,守护者就没有什么意义了。
网友评论