Java之守护线程

Java之守护线程_第1张图片
线程状态图

Java中有两种线程,一种是守护线程,一种是用户线程。守护线程和用户线程的唯一区别就是,守护线程的死亡时间是由用户线程的生存时间决定的。只有当用户线程都结束的时候,JVM会强制停止守护线程。比如:GC线程就是典型的守护线程。

  • 守护线程的注意点
    1、设置守护线程的方式是Thread.setDeamon(true)。而且要在Thread.run()方法调用之前调用。或者说,线程启动后,不能再设置其为守护线程。
    2、守护线程创建的线程也是守护线程。
    3、由于守护线程的结束不掌握在自己手中,是由JVM决定的,所以要始终认识到,守护线程中的逻辑处理随时可能被打断。故,守护线程中不能放关键业务代码。比如,读写数据库,读写文件,业务处理等。我的理解,不太重要的,非关键性的处理可以放在守护线程中。要保证,即使守护线程被突然终止了,也不会影响业务逻辑的时候才可以放在守护线程中。(JVM的垃圾回收,即使失败一次,其实也不会影响业务的执行,最多也就是内存没有及时清理而已)

  • 实验
    实验目的: 验证守护线程的结束不是由自己控制的,而是在没有用户线程的时候被jvm关闭的。
    实验代码
    1、守护线程

    // 守护线程
    public static class DeamonThread implements Runnable {

        public void run() {
            try {
                System.out.println("守护线程开始运行。");
                int i = 0;
                while (true) {
                    System.out.println("[Deamon Thread]" + i + " seconds passed.");
                    Thread.sleep(1000L);
                    I++;
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                System.out.println("守护线程结束。");
            }
        }
    }

2、用户线程

    // 用户线程
    public static class UserThread implements Runnable {

        public void run() {
            System.out.println("用户线程开始。");
            for (int i=0; i<10; i++) {
                System.out.println("[User Thread]" + i + " seconds passed.");
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            System.out.println("用户线程结束。");
        }
    }

3、主程序

public static void main(String[] args) {
        System.out.println("start...");

        //启动一个deamon线程,启动一个用户线程。用户线程启动10秒,deamon线程存活10秒。
        DeamonThread dr = new DeamonThread();
        Thread dt = new Thread(dr);
        dt.setDaemon(true);
        dt.start();

        UserThread ur = new UserThread();
        Thread ut = new Thread(ur);
        ut.start();

        System.out.println("...end");
    }

4、执行结果

start...
守护线程开始运行。
[Deamon Thread]0 seconds passed.
...end
用户线程开始。
[User Thread]0 seconds passed.
[Deamon Thread]1 seconds passed.
[User Thread]1 seconds passed.
[Deamon Thread]2 seconds passed.
[User Thread]2 seconds passed.
[Deamon Thread]3 seconds passed.
[User Thread]3 seconds passed.
[Deamon Thread]4 seconds passed.
[User Thread]4 seconds passed.
[Deamon Thread]5 seconds passed.
[User Thread]5 seconds passed.
[Deamon Thread]6 seconds passed.
[User Thread]6 seconds passed.
[Deamon Thread]7 seconds passed.
[User Thread]7 seconds passed.
[Deamon Thread]8 seconds passed.
[User Thread]8 seconds passed.
[Deamon Thread]9 seconds passed.
[User Thread]9 seconds passed.
[Deamon Thread]10 seconds passed.
用户线程结束。

实验结论
在用户进程执行10秒后,守护线程也随之结束。而且显然是被jvm强制关闭的。因为守护线程中的finally语句并没有被执行。

  • 使用建议
    尽量不要使用deamon线程。如果一定要用,三思而后行。

你可能感兴趣的:(Java之守护线程)