We know that static variables are at the classloader level. If the web application stops, these static variables will also be cleared from the JVM. However, the thread is JVM-level. If you start a thread in a web application, the lifecycle of the thread will not be synchronized with the Web application. That is to say, even if you stop the web application, this thread is still active. It is precisely because of this obscure problem that many experienced developers do not agree to start threads in Web applications without permission.
If we manually use JDK timer (quartz schedmer), start timer when the Web container is started. When the Web container is closed, unless you manually close this timer, otherwise, tasks in the timer will continue to run!
The following is a small example to demonstrate this "weird" phenomenon. We use servletcontextlistener to create a timer at Web Container startup and periodically run a task:
// Code list startjavaseruntask: Container listener
Package com. baobaotao. Web;
Import java. util. date;
Import java. util. timer;
Import java. util. timertask;
Import javax. servlet. servletcontextevent;
Import javax. servlet. servletcontextlistener;
Public class startjavaseruntask implements servletcontextlistener ...{
Private timer;
Public void contextdestroyed (servletcontextevent arg0 )...{
// ② This method is executed when the Web container is closed
System. Out. println ("Web application startup close ...");
}
Public void contextinitialized (servletcontextevent arg0 )...{
// ② Automatically execute this method when the Web Container starts
System. Out. println ("Web application startup ...");
Timer = new timer (); // ②-1: Create a timer. A background thread is automatically created in the timer.
Timertask task = new simpletimertask ();
Timer. Schedule (task, 1000l, 5000l); // ②-2: register a task that runs once every 5 seconds
}
}
Class simpletimertask extends timertask... {// ③ task
Private int count;
Public void run ()...{
System. Out. println (++ count) + "execute task..." + (new date ()));
}
}
Declare the Web Container listener in Web. xml:
<? XML version = "1.0" encoding = "UTF-8"?>
<Web-app>
...
<Listener>
<Listener-class> com. baobaotao. Web. startjavaseruntask </listener-class>
</Listener>
</Web-app>
After the web application is deployed and started in Tomcat, you can see that the task is executed every five seconds.
After running for a period of time, log on to the Tomcat management background and disable the corresponding web application (chapter13.
Go to the Tomcat console, and you will see that although the web application has been disabled, the timer task is still being executed in the same way-the stage has been removed and the play continues to perform:
You can add the timer. Cancel () code to contextdestroyed (servletcontextevent arg0) by changing the code of the starttriggeruntask list. After the Web container is closed, manually stop timer to end the task.
The timerfactorybean and schedulerfactorybean provided by spring for JDK timer and quartz scheduler can be associated with the lifecycle of the spring container. When the spring container is started, the scheduler is started. When the spring container is closed, stop the scheduler. Therefore, configuring the scheduler through the two factorybeans in spring and getting the scheduler reference from Spring IoC for task scheduling will not cause the problem that the Web container is closed and the task is still running. If you directly use timer or schedmer in the program, this problem will occur if no additional processing is performed.
Source:
Http://java.e800.com.cn/articles/2007/426/1177524100389641841_1.html