首页 > 学院 > 开发设计 > 正文

守护线程

2019-11-08 01:43:13
字体:
来源:转载
供稿:网友

java 中有两类线程:用户线程和守护线程。

守护线程的作用

守护线程的作用是为用户线程的运行提供服务,比如说 GC 线程。

创建一个守护线程

public class DaemonTest_01 { public static void main(String[] args) { Thread thread = new Thread(new DaemonRunner(), "DeamonRunner"); thread.setDaemon(true); // 设置线程为守护线程 thread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.PRintStackTrace(); } } static class DaemonRunner implements Runnable { @Override public void run() { System.out.println("守护线程启动"); System.out.println("这个线程是守护线程吗?" + (Thread.currentThread().isDaemon() ? "Yes" : "No")); } }}

输出:

守护线程启动 这个线程是守护线程吗?Yes

关键在于 thread.setDaemon(true) 这段代码。

守护线程的特点

特点一: setDaemon(true) 必须在 start() 之前,否则会有异常。你不能把正在运行的常规线程设置为守护线程。

特点二: 守护线程存在的目的是为用户线程提供服务,因此如果用户线程全部撤离,那么守护线程也就没什么存在的必要了,所以虚拟机也就退出了。所以守护线程中的 finally 块不一定会执行。

下面举例验证:

public class DaemonTest_02 { public static void main(String[] args) { Thread thread = new Thread(new DaemonRunner(), "DeamonRunner"); thread.setDaemon(true); thread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } static class DaemonRunner implements Runnable { @Override public void run() { try { System.out.println("守护线程启动"); System.out.println("这个线程是守护线程吗?" + (Thread.currentThread().isDaemon() ? "Yes" : "No")); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("进入 finally 方法"); } } }}

可能的一种输出:

守护线程启动 这个线程是守护线程吗?Yes

main 方法执行完毕后虚拟机中已经没有用户线程了,虚拟机需要退出,所有守护线程立即终止,但是 finally 块并没有执行。因此在构建守护线程时,不能依靠 finally 块中的内容来确保执行关闭或清理资源的逻辑。

特点三: 守护线程创建的新线程也是守护线程。

举例说明:

public class DaemonTest_03 { public static void main(String[] args) { Thread thread = new Thread(new DaemonRunner(), "DeamonRunner"); thread.setDaemon(true); thread.start(); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } static class DaemonRunner implements Runnable { @Override public void run() { System.out.println("守护线程启动"); System.out.println("这个线程是守护线程吗:" + (Thread.currentThread().isDaemon()?"Yes":"No")); try { Thread thread = new Thread(new Runner(), "Runner"); // thread.setDaemon(true); 注意这里并没有明确设置新线程为守护线程 thread.start(); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } static class Runner implements Runnable { @Override public void run() { System.out.println("新线程启动"); System.out.println("这个新线程是守护线程吗:" + (Thread.currentThread().isDaemon()?"Yes":"No")); } }}

输出:

守护线程启动 这个线程是守护线程吗:Yes 新线程启动 这个新线程是守护线程吗:Yes


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表