首页IT科技java守护线程的作用(Java守护线程)

java守护线程的作用(Java守护线程)

时间2025-07-30 20:50:45分类IT科技浏览8378
导读:Java中,通过Thread类,我们可以创建2种线程,分为守护线程和用户线程。...

Java中                 ,通过Thread类                         ,我们可以创建2种线程        ,分为守护线程和用户线程                 。

守护线程是所有非守护线程的保姆                 ,当所有非守护线程执行完成或退出了                          ,即使还有守护线程在运行        ,JVM也会直接退出        ,因此守护线程通常是用来处理一些辅助工作                         。

反之                          ,对于非守护线程                 ,只要有一个在运行        ,JVM就不会退出        。

典型的守护线程如垃圾回收GC线程                         ,当用户线程都结束后                 ,GC也就没有单独存在的必要,JVM直接退出                 。

我们可以通过Thread对象的setDaemon(boolean on)方法设置是否为守护线程                         ,要在start之前设置:

需要注意的是                         ,如果没有显示调用setDaemon方法进行设置,线程的模式是取决于父线程是否为守护线程                 ,也就是创建此线程所在的线程                          。

如果父线程是守护线程                         ,创建的线程默认是守护线程;

如果父线程是用户线程        ,创建的线程默认是用户线程        。

这可以从Thread类的init方法源代码中看出:

Thread parent = currentThread(); this.daemon = parent.isDaemon();

对于daemon的设置                 ,保存在了Thread对象的成员变量中                          ,Thread提供了setter/getter:

private boolean daemon = false; // 是否为守护线程 public final void setDaemon(boolean on) { // SecurityManager安全检查        ,本文不展开讨论 checkAccess(); // 检查线程是否已启动        ,已启动无法设置daemon if (isAlive()) { throw new IllegalThreadStateException(); } daemon = on; } public final boolean isDaemon() { return daemon; }

setDaemon方法中通过isAlive判断线程是否已启动                          ,已启动状态下不允许修改                 ,抛出IllegalThreadStateException异常        。

接着我们用示例来验证一下守护线程和非守护线程的区别                          。

以下是守护线程示例:

Thread t = new Thread(() -> { System.out.println("before"); ThreadUtil.sleep(5000); System.out.println("after"); }); // 显式设置daemon为true t.setDaemon(true); t.start(); ThreadUtil.sleep(1000); System.out.println("exit");

输出:

before exit

可以发现        ,当线程设置为守护线程后                         ,主线程一旦执行完毕                 ,程序退出,守护线程也随着立即终止                 。

以下是非守护线程示例:

Thread t = new Thread(() -> { System.out.println("before"); ThreadUtil.sleep(5000); System.out.println("after"); }); // 显式设置daemon为false t.setDaemon(false); t.start(); ThreadUtil.sleep(1000); System.out.println("exit");

输出:

before exit after

虽然主线程已经执行完毕                         ,但创建的非守护线程还在运行        。

具体JVM是如何通过daemon字段控制线程的                         ,这在JDK中找不到相应源码,需要深入hotspot C++源码进行分析                 ,后续有必要再追加更新                         。

声明:本站所有文章                         ,如无特殊说明或标注        ,均为本站原创发布                 。任何个人或组织                 ,在未征得本站同意时                          ,禁止复制                 、盗用                         、采集        、发布本站内容到任何网站                 、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益        ,可联系我们进行处理                         。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
vue中引入echarts(vue3使用echart的两种引入方式以及注意事项说明) 廖雪峰老师的官方网站(跟着廖雪峰学python 005)