JAVA Implementation and comparison of several Task Scheduling Methods

Source: Internet
Author: User

Http://www.ibm.com/developerworks/cn/java/j-lo-taskschedule/

Overview: most of the current Web applications have the task scheduling function. This article introduces several Java implementation methods for task scheduling, including timer, scheduler, quartz, and jcron tabs, and compares their advantages and disadvantages, the purpose is to provide valuable reference for programmers who need to schedule development tasks.

Task Scheduling refers to automatic task execution based on a given time interval or a specified number of executions. This article introduces the Java implementation of four types of task scheduling in a simple way:

  • Timer
  • Scheduledexecutor
  • Open-Source Tool Kit quartz
  • Open-source toolkit jcrontab

In addition, in order to implement complex task scheduling, this article also introduces some use methods of calendar.

Timer

I believe everyone is familiar with Java. util. timer. It is the simplest way to implement task scheduling. The following is a specific example:

Package COM. IBM. scheduler; import Java. util. timer; import Java. util. timertask; public class timertest extends timertask {private string jobname = ""; Public timertest (string jobname) {super (); this. jobname = jobname;} @ override public void run () {system. out. println ("execute" + jobname);} public static void main (string [] ARGs) {timer = new timer (); long delay1 = 1*1000; long Period1 = 1000; // after 1 second from now on, job1 timer is executed every 1 second. schedule (New timertest ("job1"), delay1, Period1); long delay2 = 2*1000; long period2 = 2000; // two seconds from now on, run job2 timer every 2 seconds. schedule (New timertest ("job2"), delay2, period2);} output: Execute job1 execute job1 execute job2 execute job1 execute job1 execute job2

The core classes of timer for task scheduling are timer and timertask. Timer is responsible for setting the start time and interval of timertask execution. You only need to create an inheritance class of timertask to implement your own run method, and then drop it to timer for execution.

The core design of timer is a tasklist and a taskthread. Timer drops the received tasks to its own tasklist. The tasklist is sorted according to the initial execution time of the task. Timerthread starts to become a daemon thread when timer is created. This thread polls all tasks, finds the most recent task to be executed, and then sleeps. At the start time of the most recent task to be executed, timerthread is awakened and executed. Then timerthread updates the latest task to be executed and continues to sleep.

Timer has the advantage of being easy to use. However, since all tasks are scheduled by the same thread, all tasks are executed in serial mode, and only one task can be executed at a time, the latency or exceptions of the previous task will affect subsequent tasks.


ScheduledExecutor

In view of the above shortcomings of timer, Java 5 has introduced scheduledexecutor Based on the thread pool design. The design idea is that every scheduled task is executed by a thread in the thread pool. Therefore, tasks are executed concurrently without interference between them. Note that scheduedexecutor is only available when the task execution time is reached.
To start a thread. scheduledexecutor is in the polling task status for the rest of the time.

Package COM. IBM. scheduler; import Java. util. concurrent. executors; import Java. util. concurrent. scheduledexecutorservice; import Java. util. concurrent. timeunit; public class scheduledexecutortest implements runnable {private string jobname = ""; Public scheduledexecutortest (string jobname) {super (); this. jobname = jobname;} @ overridepublic void run () {system. out. println ("execute" + jobname);} public static void main (string [] ARGs) {scheduledexecutorservice service = executors. newscheduledthreadpool (10); long initialdelay1 = 1; long Period1 = 1; // after 1 second, run job1service every 1 second. scheduleatfixedrate (New scheduledexecutortest ("job1"), initialdelay1, Period1, timeunit. seconds); long initialdelay2 = 1; long delay2 = 1; // run job2service every two seconds after 2 seconds. schedulewithfixeddelay (New scheduledexecutortest ("job2"), initialdelay2, delay2, timeunit. seconds) ;}} output: Execute job2execute job1execute job2execute job1execute job2execute job1
 
Listing 2 shows the two most common Scheduling Methods scheduleatfixedrate and schedulewithfixeddelay in scheduledexecutorservice. Scheduleatfixedrate each execution time is the interval from the start of the previous task to push back, that is, the execution time is initialdelay, initialdelay + period, initialdelay + 2 * period ,...; Schedulewithfixeddelay each execution time is a time interval from the end of the last task, that is, the execution time is initialdelay, initialdelay + executetime + delay, initialdelay + 2 * executetime + 2 * delay. It can be seen that scheduleatfixedrate is based on a fixed interval for task scheduling, schedulewithfixeddelay depends on the duration of each task execution, and is based on a non-fixed interval for task scheduling.
 
 
 
 
 
Both timer and scheduledexecutor can only schedule tasks based on the start time and repetition interval, and cannot meet more complex scheduling requirements. For example, set the task to be executed at 16:38:10 every Tuesday. Neither timer nor scheduledexecutor can be used for this function. However, you can use calendar to indirectly implement this function.
 
 
Package COM. IBM. scheduler; import Java. util. calendar; import Java. util. date; import Java. util. timertask; import Java. util. concurrent. executors; import Java. util. concurrent. scheduledexecutorservice; import Java. util. concurrent. timeunit; public class scheduledexceutortest2 extends timertask {private string jobname = ""; Public scheduledexceutortest2 (string jobname) {super (); this. jobname = jobname;} @ overridep Ublic void run () {system. out. println ("date =" + new date () + ", execute" + jobname);}/*** the calculation starts from the current time currentdate and meets the conditions dayofweek, hourofday, * latest, secondofminite latest time * @ return */public calendar getearliestdate (calendar currentdate, int dayofweek, int hourofday, int minuteofhour, int secondofminite) {// calculate the current time of the hour, day_of_week, hour_of_day, minute, second, and other field values int currentweekofyear = cur Expiry date. get (calendar. week_of_year); int currentdayofweek = currentdate. get (calendar. day_of_week); int currenthour = currentdate. get (calendar. hour_of_day); int currentminute = currentdate. get (calendar. minute); int currentsecond = currentdate. get (calendar. second); // if the value of dayofweek in the input condition is less than that of dayofweek of the current date, week_of_year needs to be postponed for one week Boolean weeklater = false; If (dayofweek <currentdayofweek) {F (dayofweek = currentdayofweek) {// If the input condition is equal to the dayofweek of the current date, week_of_year needs to be postponed for one week if (hourofday <currenthour) {weeklater = true;} else if (hourofday = currenthour) {// when the input condition matches the dayofweek of the current date, when the hourofday is equal, // If the minuteofhour in the input condition is less than the current date's // currentminute, week_of_year needs to be postponed for one week if (minuteofhour <currentminute) {weeklater = true ;} else if (minuteofhour = currentsecond) {// When the input condition is equal to the dayofweek, hourofday, // minuteofhour of the current date, if the value of // secondofminite in the input condition is less than the currentsecond of the current date, // week_of_year needs to be postponed for one week if (secondofminite <currentsecond) {weeklater = true ;}}} if (weeklater) {// set week_of_year in the current date to currentdate of one week in the current week. set (calendar. week_of_year, currentweekofyear + 1);} // set day_of_week, hour_of_day, minute, and second in the current date as values in the input condition. Currentdate. set (calendar. day_of_week, dayofweek); currentdate. set (calendar. hour_of_day, hourofday); currentdate. set (calendar. minute, minuteofhour); currentdate. set (calendar. second, secondofminite); Return currentdate;} public static void main (string [] ARGs) throws exception {scheduledexceutortest2 test = new scheduledexceutortest2 ("job1 "); // obtain the current time: Calendar currentdate = calendar. getinstance (); long currentdatelong = currentdate. gettime (). gettime (); system. out. println ("current date =" + currentdate. gettime (). tostring (); // calculate the last execution time that meets the conditions. Calendar earliestdate = test. getearliestdate (currentdate, 3, 16, 38, 10); long earliestdatelong = earliestdate. gettime (). gettime (); system. out. println ("earliest date =" + earliestdate. gettime (). tostring (); // calculate the interval between the current time and the last execution time. Long Delay = earliestdatelong-currentdatelong; // The computing execution cycle is one week long period = 7*24*60*60*1000; scheduledexecutorservice service = executors. newscheduledthreadpool (10); // execute job1service every week after the current delay millisecond. scheduleatfixedrate (test, delay, period, timeunit. milliseconds) ;}} output: current date = wed Feb 02 17:32:01 CST 2011 earliest date = Tue Feb 8 16:38:10 CST 2011 date = Tue Feb 8 16:38:10 CST 2011, execute job1date = Tue Feb 15 16:38:10 CST 2011, execute job1

Listing 3 provides the task scheduling function at 16:38:10 every Tuesday. The core of scheduledexceutor is to calculate the absolute time of the last Tuesday 16:38:10 based on the current time, and then calculate the time difference with the current time as a parameter to call the scheduledexceutor function. Java. util. Calendar is used to calculate the latest time. First, we need to explain some design ideas of calendar. Calendar has the following methods to uniquely identify a date:

 YEAR + MONTH + DAY_OF_MONTH  YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK  YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK  YEAR + DAY_OF_YEAR  YEAR + DAY_OF_WEEK + WEEK_OF_YEAR 


The combination of hour_of_day + minute + second is a complete time identifier. This example uses the last combination method. The input is day_of_week, hour_of_day, minute, second, and current date. The output is a future date that meets day_of_week, hour_of_day, minute, second and is closest to the current date. The calculation principle is to start from the input day_of_week. If it is less than day_of_week of the current date, it needs to enter week_of_year, that is
Week_of_year is added to overwrite the old value; if it is equal to the current day_of_week, compare hour_of_day; if it is greater than the current day_of_week, call Java directly. util. calenda's calendar. the Set (field, value) function assigns values of day_of_week, hour_of_day, minute, and second of the current date to the input values, and so on until the values are compared to second. You can select different combinations based on your input needs to calculate the latest execution time.

It can be seen that it is troublesome to use the above method to schedule the task, which requires a more complete task scheduling framework to solve these complex scheduling problems. Fortunately, the open-source tool kit quartz and jcrontab provide powerful support in this regard.

Quartz can meet more and more complex scheduling requirements. First, let's see how to use quartz to schedule every Tuesday:

Package COM. IBM. scheduler; import Java. util. date; import Org. quartz. job; import Org. quartz. jobdetail; import Org. quartz. jobexecutioncontext; import Org. quartz. jobexecutionexception; import Org. quartz. scheduler; import Org. quartz. schedulerfactory; import Org. quartz. trigger; import Org. quartz. helpers. triggerutils; public class quartztest implements job {@ override // This method implements the public void execute (jobexecutioncontext arg0) throws jobexecutionexception {system. out. println ("generating Report-" + arg0.getjobdetail (). getfullname () + ", type =" + arg0.getjobdetail (). getjobdatamap (). get ("type"); system. out. println (new date (). tostring ();} public static void main (string [] ARGs) {try {// create a schedulerschedulerfactory schedfact = new Org. quartz. impl. stdschedulerfactory (); sched1_sched = schedfact. getscheduler (); sched. start (); // create a jobdetail, specifying the name, groupname, and the specific job class name, // This job is responsible for defining the job jobdetail = new jobdetail ("myjob", "myjobgroup", quartztest. class); jobdetail. getjobdatamap (). put ("type", "full"); // create a trigger triggered every week, indicating the trigger = triggerutils to be executed several minutes in a week. makeweeklytrigger (3, 16, 38); trigger. setgroup ("mytriggergroup"); // trigger is executed from the next second of the current time. setstarttime (triggerutils. getevenseconddate (new date (); // specifies the nametrigger of the trigger. setname ("mytrigger"); // use schedgger to associate jobdetail with trigger to start sched. schedulejob (jobdetail, trigger);} catch (exception e) {e. printstacktrace () ;}} output: generating Report-myjobgroup. myjob, type = fulltue Feb 8 16:38:00 CST 2011 generating Report-myjobgroup. myjob, type = fulltue Feb 15 16:38:00 CST 2011


Listing 4 implements a complex task scheduling. The core classes designed by quartz include scheduler, job, and trigger. The job defines the task to be executed, trigger sets the scheduling policy, scheduler assembles the two, and triggers the task to start execution.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.