浅谈java中守护线程与用户线程
浅谈java中守护线程与用户线程 本篇文章主要介绍了java中守护线程与用户线程的概念和区别。Java中的线程可以分为两类,即daemon线程(守护线程)和User线程(用户线程)。守护线程是一种特殊的线程,它们的生命周期并不受主线程的影响,而用户线程则是我们可以看到的线程。 在JVM启动时,main函数所在的线程是一个用户线程,而JVM内部同时还启动了许多守护线程,如垃圾回收线程。守护线程和用户线程的主要区别在于,当最后一个非守护线程结束时,JVM会正常退出,而不管当前是否有守护线程。 守护线程的创建可以通过设置线程的daemon参数为true来实现。例如: ```java public static void main(String[] args) { Thread daemonThread = new Thread(new Runnable() { public void run() { // ... } }); daemonThread.setDaemon(true); daemonThread.start(); } ``` 在JVM中,如果有一个用户线程还没有结束,JVM就不会退出。例如,在main线程中创建了一个thread线程,thread线程里面是无限循环,运行代码后,main线程已经运行结束了,但是JVM进程并没有退出。这个结果说明了当父线程结束后,子线程还是可以继续存在的,也就是子线程的生命周期并不受父线程的影响。 如果我们把上面的thread线程设置为守护线程后,在运行时,JVM进程就会终止了。这个例子里main函数是唯一的用户线程,thread线程是守护线程,当main线程运行结束后,JVM发现当前已经没有用户线程了,就会终止JVM进程。 在JVM中,在main线程运行结束后,JVM会自动启动一个叫做DestroyJavaVM的线程,该线程会等待所有用户线程结束后终止JVM进程。这个过程可以通过JVM的代码来证明,例如: ```c int JNICALL JavaMain(void * _args){ ... // 执行Java中的main函数 (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); // main函数返回值 ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1; // 等待所有非守护线程结束,然后销毁JVM进程 LEAVE(); } ``` LEAVE是一个宏定义,用于销毁JVM进程。这个宏的作用实际是创建了一个名字叫做DestroyJavaVM的线程来等待所有非守护线程结束,然后销毁JVM进程。 本篇文章主要介绍了java中守护线程与用户线程的概念和区别,并通过例子来加深对守护线程和用户线程的理解。