Java中的守护线程与用户线程

Java中的线程分为两类,分别为daemon线程(守护线程)和user线程(用户线程)。JVM启动时调用main函数,main函数所在的线程就是一个用户线程,当然启动的时候JVM内部还启动了好多守护线程,比如垃圾回收线程。那两者区别在哪呢?当最后一个非守护线程结束时,JVM会正常退出,而不管当前是否有守护线程,也就是说守护线程是否结束并不影响JVM的退出。只要用户线程没结束,那么JVM就不会退出。设置一个线程为守护线程的方法是通过setDaemon(true)实现的,下面看一个例子:

    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (;;) {}
            }
        });
        // thread.setDaemon(true);
        thread.start();
        System.out.println("main thread is over");
    }

其中在main方法中创建了一个子线程,并执行一个死循环。运行结果如下:
Java中的守护线程与用户线程_第1张图片
能看到main线程其实是已经执行完毕,但是JVM进程并没有退出,说明此时子线程thread仍然还在执行,再利用java中的jps命令查看一下正在运行的线程,如下:
Java中的守护线程与用户线程_第2张图片
这个例子说明了如果用户线程没有结束运行的话,JVM进程不会退出,同时还能看到子线程的生命周期是不受父线程的影响的。那如果把那个线程设置为守护线程呢,即把上面代码块中的注释行取消注释,看一下运行结果:
Java中的守护线程与用户线程_第3张图片
看到运行结束了且JVM进程终止。去掉注释后,main线程成了唯一的一个用户线程,thread是守护线程,所以当main线程结束了以后不管thread是否在运行,都停止JVM进程。main线程运行结束后,JVM会自动启动一个叫做DestroyJavaVM的线程,该线程会等待所有用户线程结束后终止JVM进程。

在Tomcat的NIO实现NioEndpoint中会开启一组接受线程来接受用户的连接请求,以及一组处理线程负责具体处理用户请求,这两种线程默认都是守护线程,这意味着当tomcat收到shutdown命令后并且没有其他用户线程存在的情况下tomcat进程会马上消亡,而不会等待处理线程处理完当前的请求

你可能感兴趣的:(java多线程)