Concurrent series "User Thread and Daemon Thread"

守护线程 Daemon Thread

The daemon thread is a special kind of thread compared to the normal thread, so where is it special? Don't worry, before we understand it, we need to know one problem, that is:

Under what circumstances can the JVM program exit normally?

The Java Virtual Machine exits when the only threads running are all daemon threads.

The above sentence comes from the official JDK documentation, which means:

当 JVM 中不存在任何一个正在运行的非守护线程时,则 JVM 进程即会退出。

It is a bit abstract to understand, look at the following code:

public static void main(String[] args) throws InterruptedException {
    
    
  	// 在主线程中 new 一个非守护线程
  	Thread thread = new Thread(()->{
    
      // ① 
      	// 模拟非守护线程不退出的情况
      	while(true){
    
                      // ②
          	try{
    
    
              	// 睡眠一秒
              	TimeUnit.SECONDS.sleep(1);
              	System.out.println("I am running ...");
            }catch(InterruptedException e){
    
    
              	e.printStackTrace();
            }
        }
    });
  
  	// 启动线程
  	thread.start();     // ③
  	TimeUnit.SECONDS.sleep(2);
  
  	// 主线程即将退出
  	System.out.println("the main thread ready to exit ...");  // ④
}
  • ①: Create a non-daemon thread;
  • ②: Simulate the situation that non-daemon threads do not exit;
  • ③: Start the thread;
  • ④: The main thread is about to exit;

The results are as follows:

I am running ...
the main thread ready to exit ...
I am running ...
I am running ...
I am running ...

You can see that because there is a non-daemon thread running in the background, the JVM cannot exit normally. So, what if the daemon thread is running?

public static void main(String[] args) throws InterruptedException {
    
    
  	// 设置一个钩子线程,在 JVM 退出时输出日志
  	Runtime.getRuntime()
    .addShutdownHook(new Thread(()-> System.out.println("The JVM exit success !!!")) );
  
  	// 在主线程中 new 一个非守护线程
  	Thread thread = new Thread(()->{
    
      // ① 
      	// 模拟非守护线程不退出的情况
      	while(true){
    
                      // ②
          	try{
    
    
              	// 睡眠一秒
              	TimeUnit.SECONDS.sleep(1);
              	System.out.println("I am running ...");
            }catch(InterruptedException e){
    
    
              	e.printStackTrace();
            }
        }
    });
  
  	// 将线程设置为守护线程
    thread.setDaemon(true);
  
  	// 启动线程
  	thread.start();     // ③
  	TimeUnit.SECONDS.sleep(2);
  
  	// 主线程即将退出
  	System.out.println("the main thread ready to exit ...");  // ④
}
  • ①: Add a hook thread to monitor JVM exit and output log;

  • ②: by setDaemon(true)setting a daemon thread the thread;

operation result:

I am running ...
the main thread ready to exit ...
The JVM exit success !!!

As you can see, when the main thread exits, the JVM will exit and the daemon thread will be recycled at the same time, even if you are in an endless loop.

The role and application scenarios of the daemon thread

Through the sample code above, I believe you have already understood the difference between a daemon thread and a normal thread. Then, let's discuss why a daemon thread is needed, when to use it, and what is its application scenario?

Above, we already know that if there is not a non-daemon thread (all daemon threads) running in the JVM, the JVM will exit at this time. In other words, the daemon thread has the feature of automatically ending its life cycle, while the non-daemon thread does not have this feature.

The JVM is a 垃圾回收线程typical daemon thread. If it does not have this feature, what will happen?

When the JVM is about to exit, because the garbage collection thread is still running, the program cannot exit, which is very embarrassing! ! ! This shows the importance of the daemon thread.

Generally speaking, daemon threads are often used to perform some background tasks, but you also want the threads to be automatically shut down when the program exits, or when the JVM exits. At this time, the daemon thread is your first choice.

Summary : If you want the JVM process to end immediately after the main thread ends, you can set it as a daemon thread when you create the thread. If you want the child thread to continue working after the main thread ends, let the JVM process after the child thread ends. End, then set the child thread as a user thread.

Guess you like

Origin blog.csdn.net/weixin_44471490/article/details/109019549