Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
This section describes the concepts and precautions of Java daemon thread and user thread.
1 Definition and Overview
Threads in Java fall into two categories: daemon threads (daemons) and user threads (user threads). Daemon threads, also known as Daemon threads, run in the background and are invisible; The user thread runs in the foreground, as you can see.
The main function is called when the JVM starts, and the thread in which main is called is a user thread. In fact, several daemon threads, such as the garbage collector thread, are also started inside the JVM.
Daemon threads are a support thread because they are used primarily for background scheduling and support work within a program. This means that when there are no non-daemon threads in a Java VIRTUAL machine, the Java virtual machine will exit regardless of whether there are currently daemons, meaning that the termination of the Daemon thread does not affect JVM exit.
In fact, after the main thread finishes running, the JVM automatically starts a thread called DestroyJavaVM that will wait for all user threads to finish and terminate the JVM process.
The NioEndpoint of Tomcat’s NIO implementation opens a set of receiving threads to accept user connection requests and a set of processing threads to process user requests. By default, both the receiving and processing threads are daemon threads. This means that tomcat will die as soon as it receives shutdown and no other user thread exists, rather than wait for the processing thread to finish processing the current request.
2 Use daemon threads
Before thread start, threads can be set to Daemon threads by calling thread.setdaemon (true).
Daemons can be terminated in two ways:
- The daemon thread also has its own run(); Method, the daemon thread terminates when the background thread completes its run method.
- When the user thread finishes running, the daemon thread terminates automatically.
3 Test Cases
public class Daemon {
// Starting the class will construct two threads, the main thread and a sliver thread.
public static void main(String[] args) throws InterruptedException {
// Test non-daemon threads
// We can see that the child thread continues to output after "main thread ends ", and the program is not finished
// test1();
// Test the daemon thread
If the child thread does not continue output, the program terminates
test2();
}
/** * Tests non-daemon threads **@throws InterruptedException
*/
public static void test1(a) throws InterruptedException {
Thread thread = new Thread(() -> {
while (true) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Child thread not daemon thread"); }}); thread.start(); Thread.currentThread().sleep(1000);
System.out.println("Main thread terminated");
}
// Test the daemon thread
public static void test2(a) throws InterruptedException {
Thread thread = new Thread(() -> {
while (true) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Child thread daemon thread"); }}); thread.setDaemon(true);
thread.start();
Thread.currentThread().sleep(1000);
System.out.println("Main thread terminated"); }}Copy the code
If you look at a Java process using JPS, you can see that if the child thread is a daemon thread then the main thread terminates and the child thread terminates; If the child thread is not a daemon thread then the main thread terminates and the child thread does not terminate.
4 Precautions
Daemon threads are used to do support work, but the finally block in the Daemon thread does not necessarily execute when the Java VIRTUAL machine exits, as follows:
public class Daemon {
public static void main(String[] args) {
Thread thread = new Thread(new DaemonRunner(), "DaemonRunner");
thread.setDaemon(true);
thread.start();
}
static class DaemonRunner implements Runnable {
@Override
public void run(a) {
try {
SleepUtils.second(10);
} finally {
System.out.println("DaemonThread finally run."); }}}}Copy the code
Run the Daemon and see no output on the console. The main thread (non-daemon thread) terminates after the DaemonRunner thread is started and the main method completes. At this point, there are no non-daemon threads in the Java VIRTUAL machine and the virtual machine needs to exit. All Daemon threads in the Java VIRTUAL machine need to terminate immediately, so DaemonRunner terminates immediately, but the finally block in DaemonRunner does not execute.
When building Daemon threads, you cannot rely on the contents of the finally block to ensure that the logic to close or clean up resources is performed.
If you don’t understand or need to communicate, you can leave a message. In addition, I hope to like, collect, pay attention to, I will continue to update a variety of Java learning blog!