Original link: https://www.cnblogs.com/ziq711/p/8228255.html
User Threads and Daemon threads
There are two types of threads in Java: User thread, Daemon thread (daemon thread)
In a more popular example, any daemon is a nanny for all non-daemon threads throughout the JVM:
The daemon thread works as long as any non-daemon thread in the current JVM instance is not finished, and the daemon ends up working with the JVM only when the last non-daemon thread ends.
The role of Daemon is to facilitate the operation of other threads, the most typical application of the daemon is the GC (garbage collector), which is a competent guardian.
The only difference between user and daemon is that the virtual machine leaves: If the user thread is all out of operation, only the daemon thread is present, and the virtual machine exits. Because there is no guardian, Daemon has no work to do, there is no need to continue to run the program.
It is worth mentioning that the daemon thread is not only available inside the virtual machine, but the user can also set the daemon itself when writing the program. The following method is used to set the daemon thread.
New Thread (); // set Daemonthread as the daemon thread, default false (non-daemon thread) Daemonthread.setdaemon (true); // verifies whether the current thread is a daemon thread and returns true as the daemon thread Daemonthread.isdaemon ();
Here are a few things to note:
(1) Thread.setdaemon (true) must be set before Thread.Start () or run out of a illegalthreadstateexception exception. You cannot set a running regular thread as a daemon thread.
(2) The new thread generated in the daemon thread is also daemon.
(3) Do not assume that all applications can be assigned to daemon for service, such as read-write operations or computational logic.
Because you can't know if daemon has completed the expected service task before all the user finishes. Once the user exits, it is possible that a large amount of data has not been read or written out, and the calculation task may run differently multiple times. This is devastating to the program. The reason for this result has been said: Once all the user thread has left, the virtual machine will be out of operation.
See, it's scary to wrap the input and output logic into the daemon thread, and the string is not written to the specified file. The reason is also very simple, until the main thread completes, the daemon is still in a 1-second blocking state. This time the main thread runs out quickly, the virtual machine exits, daemon stop service, the output operation naturally failed.
//the daemon thread task to complete the file outputImportJava.io.*; classTestrunnableImplementsrunnable{ Public voidrun () {Try{Thread.Sleep (1000);//Daemon thread blocks after 1 seconds of runningFile f=NewFile ("Daemon.txt"); FileOutputStream OS=NewFileOutputStream (F,true); Os.write ("Daemon". GetBytes ()); } Catch(IOException E1) {e1.printstacktrace (); } Catch(interruptedexception E2) {e2.printstacktrace (); } } } Public classtestdemo2{ Public Static voidMain (string[] args)throwsinterruptedexception {Runnable tr=Newtestrunnable (); Thread Thread=NewThread (TR); Thread.setdaemon (true);//Setting the daemon threadThread.Start ();//start of sub-process execution } } //Run Result: There is no "daemon" string in file Daemon.txt.
Public classTest { Public Static voidMain (String args) {Thread T1=NewMycommon (); Thread T2=NewThread (NewMydaemon ()); T2.setdaemon (true);//Set as daemon threadT2.start (); T1.start (); }}classMycommonextendsThread { Public voidrun () { for(inti = 0; I < 5; i++) {System.out.println ("Thread 1" + i + "times executed! "); Try{Thread.Sleep (7); } Catch(interruptedexception e) {e.printstacktrace (); } }}}classMydaemonImplementsRunnable { Public voidrun () { for(Longi = 0; i < 9999999L; i++) {System.out.println ("Background line Cheng Di" + i + "time to execute!" "); Try{Thread.Sleep (7); } Catch(interruptedexception e) {e.printstacktrace (); } }}}
The background thread executes for the NO. 0 time!
Thread 1 executes for the NO. 0 time!
Thread 1 executes for the 1th time!
The background thread executes for the 1th time!
The background thread executes for the 2nd time!
Thread 1 executes for the 2nd time!
Thread 1 executes for the 3rd time!
The background thread executes for the 3rd time!
Thread 1 executes for the 4th time!
The background thread executes for the 4th time!
The background thread executes for the 5th time!
The background thread executes for the 6th time!
The background thread executes for the 7th time!
Process finished with exit code 0
From the above results can be seen:
The foreground thread is guaranteed to execute, and the background thread has not finished executing and exits.
In fact: The standard for the JRE to determine whether the program is finished is all the front line octave complete, regardless of the background thread state, therefore, in the use of the background county must pay attention to this problem.
Additional Information
Definition: A daemon thread-also known as a "service thread"-automatically leaves when no user thread is available to serve.
Priority: The daemon thread has a lower priority, which is used to service other objects and threads in the system.
Settings: Set the thread to "daemon" by Setdaemon (true); Set a user thread to
The way to daemon threads is to use the Setdaemon method of the thread object before the thread object is created.
Example: The garbage collection thread is a classic daemon thread, and when our program no longer has any running
Thread, the program will no longer produce garbage, the garbage collector will have nothing to do, so when the garbage collection thread is
The garbage collection thread will automatically leave the remaining threads on the JVM. It is always running in a low-level state for
Real-time monitoring and management of recyclable resources in the system.
Life cycle: The Daemon (Daemon) is a special process that runs in the background. It is independent of the control terminal and
Perform certain tasks periodically or wait to handle certain occurrences. That is
The daemon thread does not depend on the terminal, but relies on the system, "die" with the system. The Java daemon thread is
What it looks like. The JVM can exit when all the threads in the JVM are daemon threads;
or more non-daemons, the JVM does not exit.
Practical Application Examples
In a long-connected comet server-side push technology, the message push thread is set as the daemon thread, serving the servlet user thread of Chatservlet, starting the message thread in the servlet init, and once the servlet is initialized, the server is always present. Message thread exits automatically after servlet is destroyed
The container receives a servlet request, the dispatch thread picks a worker thread from the thread pool, passes the request to the worker thread, and the thread executes the Servlet's service method. When this thread is executing, the container receives another request, and the dispatch thread also selects another worker thread from the thread pool to serve the new request. The container does not care whether the request accesses the same servlet. When the container receives multiple requests to the same servlet at the same time, the servlet's service () method executes concurrently on multiple threads.
The servlet container defaults to single-instance multithreading to handle requests, which reduces the overhead of generating servlet instances, increases response time to requests, and can be used by Tomcat in Server.xml <Connector> Element sets the number of threads in the thread pool.
Why use a daemon thread?
We know that static variables are classloader levels, and if the Web application stops, these static variables are also purged from the JVM. But the thread is at the JVM level, and if you start a thread in a web app, the thread's life cycle does not stay in sync with the Web application. In other words, even if you stop the Web app, the thread is still active. Because of this very obscure problem, many experienced developers are not quite in favor of launching threads in Web applications.
If we use the JDK timer manually (Quartz scheduler), start the timer when the Web container starts, and when the Web container is closed, the task in the timer will continue to run unless you manually close the timer!
Here's a small example to illustrate this "weird" phenomenon, where we create a timer and periodically run a task with Servletcontextlistener when the Web container starts:
//Code Listing Startcycleruntask: Container listener PackageCom.baobaotao.web; Importjava.util.Date; ImportJava.util.Timer; ImportJava.util.TimerTask; Importjavax.servlet.ServletContextEvent; ImportJavax.servlet.ServletContextListener; Public classStartcycleruntaskImplementsServletcontextlistener ... { PrivateTimer timer; Public voidcontextdestroyed (servletcontextevent arg0) ... { //② This method executes when the Web container is closedSYSTEM.OUT.PRINTLN ("Web application startup shutdown ..."); } Public voidcontextinitialized (servletcontextevent arg0) ... { //② automatically executes the method when the Web container startsSYSTEM.OUT.PRINTLN ("Web application startup ..."); Timer=NewTimer ();//②-1: Create a Timer,timer inside automatically create a background threadTimerTask task =NewSimpletimertask (); Timer.schedule (Task,1000L, 5000L);//②-2: Register a task that runs once in 5 seconds } } classSimpletimertaskextendsTimerTask ... {//③ Tasks Private intcount; Public voidRun () ... {System.out.println (++count) + "Execute task ..." + (NewDate ())); } }
Declare this web container listener in XML:
<?XML version= "1.0" encoding= "UTF-8"?><Web-app>... ..<Listener> <Listener-class>Com.baobaotao.web.StartCycleRunTask</Listener-class> </Listener> </Web-app>
After you deploy this web App in Tomcat and start, you'll see that the task executes every 5 seconds.
After running for a period of time, log in to the Tomcat admin backend and close the corresponding Web application (CHAPTER13).
Go to the Tomcat console and you'll see that while the Web app is closed, the timer task is still in its own way-the stage has been removed and the entertainer continues to perform:
We can add the Timer.cancel () code in contextdestroyed (Servletcontextevent arg0) by changing the code of the list Startcycleruntask, Stop the timer manually after the Web container is closed to end the task.
The Timerfactorybean and Schedulerfactorybean provided by spring for JDK timer and Quartz Scheduler can be associated with the life cycle of the spring container, starting the scheduler when the spring container is started, The scheduler is stopped when the spring container is closed. So in spring, with these two factorybean to configure the scheduler, and then get the Scheduler reference from the spring IOC for task scheduling, there will be no problem that the Web container shuts down and the task is still running. If you use a timer or scheduler directly in your program, you will see this problem if you do not perform additional processing.
Java daemonthread daemon Thread