Declarative timers, also called automatic timers, offer a technique to declare a timer using annotations. The @Schedule annotation accepts a set of arguments defining a timer event. The annotation specifies the time the event is to occur and declares the callback method. This technique provides an easy to use and intuitive way of scheduling application tasks.
The process of creating a declarative timer includes:
The argument of the @Schedule consists of a set of time elements that correspond to fields of a ScheduleExpression
object. These fields specify when and how often a timer callback will be made. Multiple timers can be assigned to a method using the @Schedules annotation.
The callback method will frequently be passed a single Timer
object. The Timer
object passed can be used to obtain additional information about the timer.
Add a method to the SystemReportManager
class called displayMemoryReport
. Annotate the method with the @Schedule annotation as shown below. This set of arguments defines a timer that will call back the displayMemoryReport
every 10 seconds. The use of the calendar-based timer is explained in more detail in the Understanding calendar-based scheduling recipe. In the method, add println
statements to display the execution of the method and the results of the getMemoryReport
method.
@Schedule(second = "0,10,20,30,40,50", minute="*", hour = "*") public void displayMemoryReport(Timer timer) { System.out.println("SystemReportManager: displayMemoryReport occurred"); System.out.println(getMemoryReport()); }
Deploy the application. There is no need to execute the application as the timer starts when the EJB is loaded. The output should be similar to the following. While it is not complete, your output should show the execution of the callback method every 10 seconds.
INFO: SystemReportManager: displayMemoryReport occurred
INFO: Jan 5, 2011 4:22:50 PM
Total Memory: 270569472
Maximum Memory: 518979584
Free Memory: 149789352
INFO: SystemReportManager: displayMemoryReport occurred
INFO: Jan 5, 2011 4:23:00 PM
Total Memory: 270569472
Maximum Memory: 518979584
Free Memory: 148865080
INFO: SystemReportManager: displayMemoryReport occurred
INFO: Jan 5, 2011 4:23:10 PM
Total Memory: 270569472
Maximum Memory: 518979584
Free Memory: 147933616
The @Schedule annotation consisted of a list of 10 second increments which specified when the report was generated. The asterisk in the minute and hour fields indicated that it should execute every minute and hour. This resulted in the displayMemoryReport
executing every 10 seconds. It displayed memory usage information obtained from the getMemoryReport
method.
In addition to the single use of the @Schedule annotation, we can use @Schedule annotations with multiple methods in an EJB. In addition, we can apply more than one @Schedule annotation to a method using the @Schedules annotation.
More than one method of an EJB can be annotated with @Schedule. Here, a second method called clearStatistics
has been added and is called once a minute.
@Schedule(second = "0", minute="*", hour = "*") public void clearStatistics(Timer timer) { System.out.println("clearStatistics executed"); }
When the application deploys you should see the execution of both of the callback methods.
INFO: SystemReportManager: displayMemoryReport occurred
INFO: Jan 5, 2011 4:32:50 PM
Total Memory: 270569472
Maximum Memory: 518979584
Free Memory: 143028648
INFO: clearStatistics executed
INFO: SystemReportManager: displayMemoryReport occurred
INFO: Jan 5, 2011 4:33:00 PM
Total Memory: 270569472
Maximum Memory: 518979584
Free Memory: 141976424
The @Schedules annotation allows us to assign multiple timers to the same method. This annotation has an argument consisting of an array of @Schedule annotations. In this example, the displayMemoryReport
method is annotated with the @Schedules annotation and two @Schedule annotations. They specify that the callback method should be executed every minute and at 20 and 30 seconds after the minute.
@Schedules( {@Schedule(second = "0", minute="*", hour = "*"), @Schedule(second = "20,30", minute="*", hour = "*")}) public void displayMemoryReport(Timer timer) { System.out.println("SystemReportManager: displayMemoryReport occurred"); System.out.println(getMemoryReport()); }
When deployed, your output should appear similar to the following:
INFO: SystemReportManager: displayMemoryReport occurred
INFO: Jan 5, 2011 4:43:00 PM
Total Memory: 270569472
Maximum Memory: 518979584
Free Memory: 146682928
INFO: SystemReportManager: displayMemoryReport occurred
INFO: Jan 5, 2011 4:43:20 PM
Total Memory: 270569472
Maximum Memory: 518979584
Free Memory: 144880096
INFO: SystemReportManager: displayMemoryReport occurred
INFO: Jan 5, 2011 4:43:30 PM
Total Memory: 270569472
Maximum Memory: 518979584
Free Memory: 144050896
3.147.71.94