amount! Is there such a big difference between user threads and daemon threads in Java?

amount! Is there such a big difference between user threads and daemon threads in Java?

Threads in the Java language are divided into two categories: user threads and daemon threads, and the difference between the two is rarely known, so this article Lei Ge will take you to see the difference between the two, as well as some of the daemon threads need to pay attention to matter.

1. The default user thread

In the Java language, whether it is a thread or a thread pool, it is a user thread by default , so user threads are also called ordinary threads.

Take the thread as an example, if you want to check whether the thread is a daemon thread, you only need to call

isDaemon()
Method query, if the query value is
false
It means that it is not a daemon thread, and naturally belongs to a user thread, as shown in the following code:

public static void main (String[] args) throws InterruptedException { Thread thread = new Thread( new Runnable() { @Override public void run () { System.out.println( "I am a child thread" ); } }); System.out.println( "Child thread == daemon thread:" + thread.isDaemon()); System.out.println( "Main thread == daemon thread:" + Thread.currentThread().isDaemon()); } Copy code

The execution result of the above program is: As can be seen from the above result , the main thread and the new thread created are both user threads by default .

PS: Thread.currentThread() means to get the thread instance that executes the current code.

2. Actively modify to a daemon thread

Daemon Thread (Daemon Thread) is also called background thread or service thread. The daemon thread serves the user thread . When all the user threads in the program are executed, the daemon thread will also end.

The role of the daemon thread is like a "server", and the role of a user thread is like a "customer". When all the "customers" are gone (all execution ends), the "server" (daemon thread) has no meaning. , So when all user threads in a program finish executing, then no matter whether the daemon thread is still working or not, it will end with the user thread, and the entire program will also finish running.

How to change the default user thread to a daemon thread?

This question should be answered in two cases. 1. if it is a thread, you can set

setDaemon(true)
Method directly modify the user thread to a daemon thread, and if it is a thread pool, you need to pass
ThreadFactory
Each thread in the thread pool is a daemon thread. Next, let's implement it separately.

2.1 Set the thread as a daemon thread

If you are using threads, you can pass

setDaemon(true)
The method changes the thread type to daemon thread, as shown in the following code:

public static void main (String[] args) throws InterruptedException { Thread thread = new Thread( new Runnable() { @Override public void run () { System.out.println( "I am a child thread" ); } }); //Set the child thread as a daemon thread thread.setDaemon( true ); System.out.println( "Child thread == daemon thread:" + thread.isDaemon()); System.out.println( "Main thread == daemon thread:" + Thread.currentThread().isDaemon()); } Copy code

The execution result of the above program is:

2.2 Set the thread pool as a daemon thread

To set the thread pool as a daemon thread is relatively troublesome, you need to set all threads in the thread pool as a daemon thread, this time you need to use

ThreadFactory
To define the thread type of each thread in the thread pool, the specific implementation code is as follows:

//Create a fixed number of thread pool ExecutorService threadPool = Executors.newFixedThreadPool( 10 , new ThreadFactory() { @Override public Thread newThread (Runnable r) { Thread t = new Thread(r); //Set the thread as a daemon thread t.setDaemon( false ); return t; } }); Copy code

As shown in the figure below: As shown in the figure above, it can be seen that there are 10 daemon threads in the entire program that I created. The other ways to create a thread pool are similar, all through

ThreadFactory
The unified settings are not listed here.

3. Daemon thread VS user thread

Through the previous study, we can create two different thread types. What is the difference between the two? Next, let's take a look at a small example.

Next we create a thread, set this thread as a user thread and a daemon thread, and execute one in each thread

for
Circulate, execute information printing 10 times in total, sleep for 100 milliseconds after each printing, to observe the running result of the program.

3.1 User thread

The newly created thread is the user thread by default, so we don t need to perform any special processing on the thread.

for
Just loop (a total of 10 information printing is performed, and sleep for 100 milliseconds after each printing). The implementation code is as follows:

/** * Author: Java Chinese Community */ public class DaemonExample { public static void main (String[] args) throws InterruptedException { Thread thread = new Thread( new Runnable() { @Override public void run () { for ( int i = 1 ; i <= 10 ; i++) { //Print i information System.out.println( "i:" + i); try { //Sleep for 100 milliseconds Thread.sleep( 100 ); } catch (InterruptedException e) { e.printStackTrace(); } } } }); //start thread thread.start(); } } Copy code

The execution results of the above program are as follows: From the above results, it can be seen that the process will be terminated normally after the program has executed 10 times of printing.

3.2 Daemon thread

/** * Author Java */ public class DaemonExample { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 10; i++) { // i System.out.println("i:" + i); try { // 100 Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }); //Set as a daemon thread thread.setDaemon( true ); //Start thread thread.start(); } } Copy code

The execution results of the above program are as follows: As can be seen from the above results, when the thread is set as a daemon thread, the entire program will not wait for the daemon thread

for
After the loop 10 times, it is closed, but when the main thread ends, the daemon thread only executes the loop once and then ends its operation. From this we can see the difference between the daemon thread and the user thread.

3.3 Summary

The daemon thread serves the user thread. When all user threads in a program are executed, the program will end. When the program ends, it will not care whether the daemon thread is running or not . From this we can see that the daemon thread is in Java The weight in the system is relatively low.

4. Note for daemon threads

The use of daemon threads requires attention to the following three issues:

  1. Daemon thread settings
    setDaemon(true)
    Must be placed in the thread
    start()
    Before, otherwise the program will report an error.
  2. All child threads created in the daemon thread are daemon threads.
  3. use
    jojn()
    The method waits for a thread to finish executing, regardless of whether the thread is a user thread or a daemon thread.

Next, we will demonstrate the above considerations separately.

4.1 setDaemon execution order

When we will

setDaemon(true)
Set at
start()
After that, as shown in the following code:

public static void main (String[] args) throws InterruptedException { Thread thread = new Thread( new Runnable() { @Override public void run () { for ( int i = 1 ; i <= 10 ; i++) { //Print i information System.out.println( "i:" + i + ",isDaemon:" + Thread.currentThread().isDaemon()); try { //Sleep for 100 milliseconds Thread.sleep( 100 ); } catch (InterruptedException e) { e.printStackTrace(); } } } }); //start thread thread.start(); //Set as a daemon thread thread.setDaemon( true ); } Copy code

The execution results of the above program are as follows: From the above results, we can see that when we

setDaemon(true)
Set at
start()
After that, not only will the execution of the program report an error, but the set daemon thread will not take effect.

4.2 Child thread of daemon thread

public static void main (String[] args) throws InterruptedException { Thread thread = new Thread( new Runnable() { @Override public void run () { Thread thread2 = new Thread( new Runnable() { @Override public void run () { } }); System.out.println( "The child thread thread2 isDaemon of the daemon thread:" + thread2.isDaemon()); } }); //Set as a daemon thread thread.setDaemon( true ); //Start thread thread.start(); Thread.sleep( 1000 ); } Copy code

The execution results of the above program are as follows: As can be seen from the above results, the child threads created in the daemon thread also belong to the daemon thread by default .

4.3 join and daemon threads

From the content of section 3.2, we can see that the program ends by default and does not wait for the execution of the daemon thread, and when we call the thread s wait

join()
When, the result of execution will be different from the result of 3.2. Let's take a look at it together. The sample code is as follows:

public static void main (String[] args) throws InterruptedException { Thread thread = new Thread( new Runnable() { @Override public void run () { for ( int i = 1 ; i <= 10 ; i++) { //Print i information System.out.println( "i:" + i); try { //Sleep for 100 milliseconds Thread.sleep( 100 ); } catch (InterruptedException e) { e.printStackTrace(); } } } }); //Set as a daemon thread thread.setDaemon( true ); //Start thread thread.start(); //Wait for the thread to finish thread.join(); System.out.println( "Child thread == daemon thread:" + thread.isDaemon()); System.out.println( "Main thread == daemon thread:" + Thread.currentThread().isDaemon()); } Copy code

The execution results of the above program are as follows: From the above results, we can see that even if it is a daemon thread, when the program is called

join()
In the method, the program will still wait for the daemon thread to finish executing before terminating the process.

5. Application scenario of daemon thread

The typical application scenario of the daemon thread is the garbage collection thread . Of course, there are some scenarios that are also very suitable for the use of the daemon thread, such as the server-side health detection function. For a server, the health detection function belongs to non-core non-mainstream service business, like this For the business function of the main business service, it is very suitable to use the daemon thread. When the main business in the program is executed, the service business will be destroyed with the follower.

6. The execution priority of the daemon thread

First of all, the type of thread (user thread or daemon thread) does not affect the priority of thread execution. As shown in the following code, define a user thread and daemon thread to execute 100,000 cycles respectively, by observing the final print result. Confirm the effect of thread type on program execution priority.

public class DaemonExample { private static final int count = 100000 ; public static void main (String[] args) throws InterruptedException { //Define task Runnable runnable = new Runnable() { @Override public void run () { for ( int i = 0 ; i <count; i++) { System.out.println( "Thread of execution:" + Thread.currentThread().getName()); } } }; //Create daemon thread t1 Thread t1 = new Thread(runnable, "t1" ); //Set as daemon thread t1.setDaemon( true ); //Start thread t1.start(); //Create user thread t2 Thread t2 = new Thread(runnable, "t2" ); //Start thread t2.start(); } } Copy code

The execution results of the above program are as follows: From the above results, it can be seen that the type of thread, whether it is a daemon thread or a user thread, has no effect on the priority of program execution.

t2
When the priority of is adjusted to the maximum, the running result of the entire program is completely different, as shown in the following code:

public class DaemonExample { private static final int count = 100000 ; public static void main (String[] args) throws InterruptedException { //Define task Runnable runnable = new Runnable() { @Override public void run () { for ( int i = 0 ; i <count; i++) { System.out.println( "Thread of execution:" + Thread.currentThread().getName()); } } }; //Create daemon thread t1 Thread t1 = new Thread(runnable, "t1" ); //Set as daemon thread t1.setDaemon( true ); //Start thread t1.start(); //Create user thread t2 Thread t2 = new Thread(runnable, "t2" ); //Set the priority of t2 to the highest t2.setPriority(Thread.MAX_PRIORITY); //start thread t2.start(); } } Copy code

The execution results of the above program are as follows: From the above results, it can be seen that the type of the program has nothing to do with the priority of program execution. When the default priority of the newly created thread is 5, whether it is a daemon thread or a user thread, The priority of their execution is the same. When the priority of the two is set different, the result of the execution will also change (the higher the priority is set, the greater the probability of being executed first).

7. Summary

In the Java language, threads are divided into user threads and daemon threads. The daemon threads are used to serve user threads. When all user threads in a program are finished, no matter whether the daemon threads are working or not, they will end with the user threads. From the perspective of business logic, the weight of the daemon thread is relatively low, but for the thread scheduler, whether it is a daemon thread or a user thread, the probability of being executed under the same priority is the same. The classic usage scenario of the daemon thread is the garbage collection thread, and the threads created in the daemon thread are also daemon threads by default.

Follow the public account "Java Chinese Community" to see more interesting and knowledge-enhancing concurrent programming articles.