java 线程 退出sleep java如何退出线程_JVM


众所周知在学习Java线程的相关知识的时候会学习到守护线程的知识,通过学习我们知道守护线程就像是“一个成功男人背后的女人”一样的存在,它在后台默默处理着一些“油盐酱醋茶”之类的工作,例如JVM中的垃圾回收器工作时的垃圾回收线程。

如何设置守护线程

调用Thread类的setDaemon()方法设置,我们看下源码:

/** * Marks this thread as either a {@linkplain #isDaemon daemon} thread * or a user thread. The Java Virtual Machine exits when the only * threads running are all daemon threads. * *

This method must be invoked before the thread is started. * * @param on * if {@code true}, marks this thread as a daemon thread * * @throws IllegalThreadStateException * if this thread is {@linkplain #isAlive alive} * * @throws SecurityException * if {@link #checkAccess} determines that the current * thread cannot modify this thread */public final void setDaemon(boolean on) { checkAccess(); if (isAlive()) { throw new IllegalThreadStateException(); } daemon = on;}


看代码的注释“The Java Virtual Machine exits when the only threads running are all daemon threads.”意思:当运行的线程都是守护线程的时候JVM就退出了。也就是说JVM的退出条件是没有一个非守护线程的时候JVM会退出。

守护线程的特点

通过源码上的注释我们可以引申出来:用户线程完成工作之前不会自动结束生命周期,守护线程具备自动结束生命周期的能力。

我们通过代码看一下:

public class DaemonThread { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { while (true){ try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }); //设置为守护线程,如果注释掉则程序不会退出结束,即使Main线程执行完毕 thread.setDaemon(true); thread.start(); System.out.println("Main thread finished"); }}

上述代码我们new了一个Thread,通过thread.setDaemon(true);设置它为守护线程,运行程序控制台打印"Main thread finished"之后,程序随之退出,如果注释掉这一行代码,控制台一样打印“"Main thread finished",但程序不会退出。如图:


java 线程 退出sleep java如何退出线程_Java_02


守护线程用来干什么

守护线程的主要作用就是为其它用户线程的运行提供便利服务,典型案例如GC线程。

1、用户线程工作生产新的对象,GC作为守护者进行后台清理,JVM退出GC也跟着退出。

2、一些需要在后台执行获取一些主线程需要的数据等场景时,可以考虑用守护线程。如:玩儿家玩游戏的时候,后台线程获取更新用户的经验值等信息,玩儿家退出游戏,后台线程也退出。

3、例如:Disruptor中使用守护线程处理事件处理器等待事件从RingBuffer中可以使用的时候获取sequence等操作。