Author: Xu Rongsheng lot of friends used the Windows Task Scheduler, there are many fans of the program he had written a clock alarm, the system automatically shut down and other fun program, very few friends can achieve similar functionality in the Web project. Today, I have a similar feature that I have achieved on Tomcat has moved out of you.
As early as a few years ago, our company cooperated with a city finance bureau, and implemented the Finance Bureau Data Center project in order to strengthen the effective supervision and implementation of the financial situation belonging to the unit. This item uses B / S plus C / S mixed structural mode. The Financial Bureau's Web Server sets the data synchronous receiving device, and the financial information is uploaded from the HTTP protocol to the central server through the HTTP protocol, and the receiving device on the web server will be docked with the receiving device on the web server every day. The internal departments of the Finance Bureau need to consult a large number of financial information, obtain the current financial status information of the completed municipal units, and each department is divided according to functions, requiring accurate access to the summary information of each department, and is provided in the form of a financial statement.
Because of the large amount of financial data, the speed of fiscal statements is slower, consider using the report cache to mitigate the burden on the server, but the cache requires a reasonable cache update mechanism. Considering that the municipal units upload financial data every day, the finance information to be found every day does not include the day (unless a leader is waiting until all the units are all uploaded, they should have been off work. Therefore, if the task plan scheduling is possible, the day and historical financial information summarize, update the cache, and the speed bottleneck is not solved.
At that time, due to the Web deployment based on the system, the report computing engine also deployed on the Tomcat container, so if you want to borrow Windows task plan to implement timed calculations, you need to have an additional normal desktop application interface, which is slightly complicated. So I wonder the implementation of the Web, after receiving more related materials, discovering the functionality of the Java Timer (Java.util.Timer), by configuring the timer's interval, after a certain time period It will automatically have regular calls pre-scheduled tasks (java.util.timertask). In addition, since we want to start timing when the web engineering starts, the timer can trigger a report computing engine at night every night in the lifetime of the entire Web Project. Therefore, the storage position of the timer is also worth examined, and it is not possible to exist in a single servlet or JavaBean. It must be able to make the regulator host's survival period of the entire web engineering life, which can be automatically loaded automatically when the project is started. Combined with these two points, the listener associated with the servlet context is the most appropriate, by reasonable configuration in the project's configuration file, will automatically run at the engineering startup, and in the monitoring state throughout the project life.
The Servlet listener combines the Java timer to describe the entire implementation process. To use the servlet listener, you need to implement the Javax.Servlet.ServletContextListener interface, and implement two interface functions for its ContextInitialized (ServletContext Event) and ContextDestroyed (ServletContext Event). Considering the process of establishing and destroying the timer, watching the two interface functions, it is not suspected to set the established process into contextIzitialized, and put the destruction process into contedentroyed.
I named the implementation class of ServletContextListener as ContextListener, add a timer in it, and the sample code is as follows (for consideration of the space, only partial code is provided for reader reference):
private java.util.Timer timer = null; public void contextInitialized (ServletContextEvent event) {timer = new java.util.Timer (true);. event.getServletContext () log ( "timer has started"); timer.schedule ( New mytask (Event.getServletContext (), 0, 60 * 60 * 1000); Event.getServletContext (). log ("Add Task Scheduling Table");} Public Void ContextDestroyed (ServletContext Event) {Timer.Cancel () Event.getServletContext (). log ("Timer Destruction");} Timer.Schedule (New Mytask (New MyTask (New MyTServletContext ()), 0, 60 * 60 * 1000) This behavior timer scheduling statement Among them, MyTask is a custom task that needs to be scheduled (in my financial data center project is the report computing engine entry), inherits from java.util.timertask, the following focuses, the third parameter is indicated by hour (ie 60 * 60 * 1000 milliseconds) is triggered once, and the intermediate parameter 0 indicates no delay. Other code is quite simple, no longer detailed.
Here's the implementation of MyTask. In the above code, when constructing MyTask, it is incorporated into the Javax.Servlet.ServletContext type parameter, which is incompatible for the record servlet log, so you need to overload the MYTASK constructor (its parent class) The Java.util.Timertask original constructor is no parameter). In the schedule of Timer.Schedule (), set once per hour, so if you want to implement the scheduled task every 24 hours, it is necessary to judge the clock point, indicated by constant c_schedule_Hour (12 o'clock in the evening, 0 points) ). At the same time, in order to prevent it from being executed 24 hours, the task has not been executed (of course, the general task is not so long), avoiding the second time being scheduled to cause conflicts, setting the status flag ISRunning that is currently executing. The sample code is as follows:
private static final int C_SCHEDULE_HOUR = 0; private static boolean isRunning = false; private ServletContext context = null; public MyTask (ServletContext context) {this.context = context;} public void run () {Calendar cal = Calendar.getInstance (); IF (! isrunning) {if (c_schedule_Hour == Cal.get (Calendar.Hour_Of_Day)) {isrunning = true; context.log ("Start the specified task");
// TODO adds a custom detailed task, the following is just example INT i = 0; while (i <10) {context.log ("" i "/" 10);} isrunning = false; Context.log ("Specify Task Execution End");}} Else {Context.log ("The last task is executed is not yet ended");}} The above code "// Todo ..." is true The demo code of the scheduled execution (in my financial data center project is the report calculation process), you can replace the statement you wish to perform.
It's been complete here, servletContextListener and MyTask's code is complete. The last step is to deploy servletContextListener to your web project, add the following three lines in your web.xml configuration file:
Of course, the top of com.test is replaced with your own package. After saving the web.xml file, deploy the engineering package to Tomcat. The task will be executed between 12 o'clock to 1 o'clock every night, the above code is recorded in Tomcat's log files:
2003-12-05 0:21:39 Started to implement the designated task 2003-12-05 0:21:39 Completed 1/10 ... 2003-12-05 0:21:39 10/102003 of the completed task -12-05 0:21:39 Specify the end of the task
The above code is debugged on Tomcat 4.1.29 and Tomcat 5.0.16.