Java

java 并发 守护线程

2020-05-09  本文已影响0人  静享时光

后台线程也叫守护线程。可以在调用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也是非守护线程)没有结束,守护线程就不会结束;
如果全部的非守护线程都结束,守护线程就结束。
可以简单理解为:没有被守护者了,守护者就没有什么意义了。

上一篇 下一篇

猜你喜欢

热点阅读