前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java并发-守护线程-Daemon

Java并发-守护线程-Daemon

作者头像
Fisherman渔夫
发布2020-02-18 16:27:11
4630
发布2020-02-18 16:27:11
举报
文章被收录于专栏:渔夫渔夫渔夫

1.代码示例:

CodeBlock-1:

1.1 守护线程在main线程中创建

public class DaemonThread {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName() + " is Starting");
        Thread t = new Thread() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " is Starting");
                try {
                    Thread.sleep(10_00);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " is finished.");
            }
        };

        // 设置为守护线程
        t.setDaemon(true);

        t.start();
        try {
            Thread.sleep(5_00);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " is finished.");
    }
}

 我们如上在main线程中定义了一个子线程t,将子线程的run方法写为sleep调用比main方法的sleep调用更久时间,以验证父类线程main的执行完毕并释放对子线程有无影响。 控制台输出:

main is Starting
Thread-0 is Starting
main is finished.
Process finished with exit code 0//此代表所有线程执行完毕,并退出

 由控制台可知,子线程中的System.out.println(Thread.currentThread().getName()+" is finished.");语句并没能够得到执行,这是因为子线程比父线程sleep更久,在子类线程sleep期间,父类线程已执行完毕,子类线程没能再次在CPU中得到权限运行,被JVM关闭了线程。

1.2 在main线程中创建普通线程

CodeBlock-2:  此处将CodeBlock-2代码中的子线程设置为守护线程的代码注释掉。

    // 设置为守护线程
//        t.setDaemon(true);

 控制台输出:

main is Starting
Thread-0 is Starting
main is finished.
Thread-0 is finished.
Process finished with exit code 0 //此代表所有线程执行完毕,并退出

 此处子线程中的System.out.println(Thread.currentThread().getName()+" is finished.");语句得到了执行,虽然子线程比父线程sleep更久,但是此时父类线程的消亡对子线程不产生影响,这样一来,子线程中的上述语句总是能够得到执行。

1.3 线程的非正常退出

 我们对于CodeBlock-2中的run语句内最后加上以下代码

 while(true){
                    //donothing
                }

 在IDE的控制台,我们只能得到以下结果显示:

main is Starting
Thread-0 is Starting
main is finished.
Thread-0 is finished.

 并没有显示Process finished with exit code 0的提示,说明子线程 Thread-0一直在内存中运行,如果使用Jconsole可以看到。我们只能选择Console上的Stop Process 键来结束线程的运行,控制台会最后打上:Process finished with exit code -1,表面有线程未执行完毕,被强制关闭了。

2. Daemon语法说明:

  1. 通过setDaemon()方法参数设置为true,将线程变为守护线程,并且此方法要在start()方法之前调用,否则会报异常
  2. 守护线程随着创建它的父线程的线程销毁而被销毁(如果当前只有Daemon线程在运行,JVM会自动关闭所有线程)
  3. 守护线程一般作为辅助性程序使用,避免某些非主要功能一直是活动线程,导致JVM不能退出
  4. 一个例子:比如一个主线程执行A、B端口的通信,主线程还创建一个子线程HealthCheck,来进行两端之间有无心跳(即,通信存在),若不存在告诉主线程,主线程重启或关闭。但是主线程关闭,其创建的子线程可能未关闭,一直在进行心跳检查,这样一来,有线程非正常关闭,主线程关闭了,可能其创建的子线程都无法通过其他方式关闭了,而Daemon则是为了解决这个问题而设计的关键词。
  5. 注意事项:如果设计为守护线程,父线程运行结束会强制结束子线程,尽管子线程代码并未执行完。但是我们不能将子线程理解为运行在父线程内部的线程, 它们对于CPU去调度,也有一定的竞争关系,而不是一个比另一个有固定的优先级顺序。这个就是案例: DaemonThread 所示,如果不是守护线程,子类线程总是会运行完毕(不管创建其的父线程的运行情况),除非任务在while(true)中运行。
  6. 在守护线程中新建一个线程, 如果这个新线程不进行setDaemon(true)的设置,那么默认继承父线程的isDaemon(true)
  7. Daemon对于所有线程不是说都应该创建,父线程消亡时子线程即可消亡一方面易于关闭线程,另一方面,也会造成子线程意外消亡的情况,特别是在强调子线程独立性,必须要执行完毕的情况下,不适合设置为守护线程。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.代码示例:
    • 1.1 守护线程在main线程中创建
    • 1.2 在main线程中创建普通线程
    • 1.3 线程的非正常退出
    • 2. Daemon语法说明:
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档