Daemon线程的创建以及使用场景分析

Daemon线程的创建以及使用场景分析

首先我们先创建一个普通的线程,我们知道main方法实际也是个线程,让他们交替打印文字:

/**
 * @program: ThreadDemo
 * @description: 守护线程demo
 * @author: hs96.cn@Gmail.com
 * @create: 2020-08-28
 */
public class DaemonThread {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread().getName() + " running");
                    Thread.sleep(3_000);
                    System.out.println(Thread.currentThread().getName() + " done");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        t.start();
        System.out.println(Thread.currentThread().getName());
    }
}

执行效果如下:

接下来把Thread t 设置为守护线程:

/**
 * @program: ThreadDemo
 * @description: 守护线程demo
 * @author: hs96.cn@Gmail.com
 * @create: 2020-08-28
 */
public class DaemonThread {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread().getName() + " running");
                    Thread.sleep(5_000);
                    System.out.println(Thread.currentThread().getName() + " done");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        t.setDaemon(true);
        t.start();

        Thread.sleep(3_000);
        System.out.println(Thread.currentThread().getName());
    }
}

执行效果如下:

见这时当main线程一结束,我们的t线程就退出了,因为没打印Thread-0 done。其实守护线程的使用场景还是有很多的,比如:当客户端与服务器端建立一个TCP的长链接,然后当连接建立之后就创建一个线程来给服务器发送心跳包以便服务器能监听客户端的网络状态,这时如果连接断开了那这个心跳线程也得跟着断开,接下来用代码模拟一下这个操作:

/**
 * @program: ThreadDemo
 * @description: 模拟客户端与服务器端建立一个TCP的长链接发送心跳包
 * @author: hs96.cn@Gmail.com
 * @create: 2020-08-28
 */
public class DaemonThread2 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            System.out.println("tcp connection...");
            Thread innerThread = new Thread(() -> {
                try {
                    while (true) {
                        System.out.println("packet sending...");
                        Thread.sleep(1_000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }, "innerThread");
            innerThread.setDaemon(true);
            innerThread.start();

            try {
                Thread.sleep(4_000);
                System.out.println("tcp Disconnect...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread");
        thread.start();
    }
}

运行效果如下:

可以看到:我们将发送心跳包的线程设置为守护线程,这个线程随着tcp连接的线程关闭而关闭了。

有一点值得一提:setDaemon 必须放在start前

posted @ 2020-08-28 03:28  风暴松鼠  阅读(352)  评论(0)    收藏  举报