The Timer
interface has a number of methods that can be used by the callback method to assist in the execution of the callback. This interface is useful to obtain information about the timer event and in passing information to the event. The use of these methods is illustrated in this recipe.
The basic steps involve:
Timer
object Timer
interface methodsThe @Schedule annotated method is passed an instance of the Timer
object. For programmatic timers, the @Timeout annotated method is passed the Timer
object. These callback methods can subsequently use this object to control the callback. The Timer
interface's methods of interest to us include:
getInfo
Returns information provided by the caller when the timer was createdgetNextTimeout
Returns a Date
object representing the time when the callback method will be executed nextgetSchedule
Returns a ScheduleExpression
for the timergetTimeRemaining
- Returns the number of milliseconds until the callback method will be called backisCalendarTimer
Returns true
if the timer is a calendar-based timerisPersistent
Returns true
if the timer is persistentTo demonstrate the use of the Timer
interface, add a getTimerData
method which is passed a Timer
object. In the method, call each of the previous Timer
interface methods. Use these methods to build a string to return at the completion of the method.
public String getTimerData(Timer timer) { StringBuilder timerData = new StringBuilder(); timerData.append(" Info: ").append(timer.getInfo()); timerData.append(" Next timeout: ").append(timer.getNextTimeout()); timerData.append(" Schedule: ").append(timer.getSchedule()); timerData.append(" Time remaining: ").append(timer.getTimeRemaining()); timerData.append(" Calendar timer: ").append(timer. isCalendarTimer()); timerData.append(" Persistent: ").append(timer.isPersistent()); return timerData.toString(); }
Next, modify the displayMemoryReport's
@Schedule annotation so it is call backed once a second. Also, invoke the getTimerData
method with the timer variable.
@Schedule(second="0", minute="*", hour = "*") public void displayMemoryReport(Timer timer) { System.out.println("SystemReportManager: displayMemoryReport occurred"); System.out.println(getMemoryReport()); System.out.println(getTimerData(timer)); }
When the application is deployed, your output will appear similar to the following:
INFO: Jan 5, 2011 8:38:00 PM
Total Memory: 270569472
Maximum Memory: 518979584
Free Memory: 107203800
INFO: Info: null
Next timeout: Wed Jan 05 20:39:00 CST 2011
Schedule: ScheduleExpression [second=0;minute=*;hour=*;dayOfMonth=*;month=*;dayOfWeek=*;year=*;timezoneID=null;start=null;end=null]
Time remaining: 59320
Calendar timer: true
Persistent: true
Notice that the getInfo
method returns null
. If we wanted to pass additional information to the callback method, we could use the information attribute, info
, and assign it a value. Here, a simple string is assigned. The displayMemoryReport
has been modified below to not display the timer data if the string is set to NoTimerData
.
@Schedule(second="0", minute="*", hour = "*", ) public void displayMemoryReport(Timer timer) { System.out.println("SystemReportManager: displayMemoryReport occurred"); System.out.println(getMemoryReport()); if(!"NoTimerData".equals(timer.getInfo())) { System.out.println(getTimerData(timer)); } }
The output should not display the timer data. This data should be Serializable
in the case of a persistent timer. Should a failure occur, it will be necessary to restore the timer and any data associated with it.
We created a getTimerData
method that used several of the Timer
interface methods. The output of these methods was concatenated to a StringBuilder
object and returned as a string to the displayMemoryReport
method. In the last example, we used the info attribute to control whether timer information was displayed or not.
Information can also be added to the Timer
object when a timer is created programmatically. The createCalendarTimer
method has a TimerConfig
argument. Using its setInfo
method, we can assign a string or any other object which implements the Serializable
interface.
In addition, two of the createTimer
methods support the creation of interval timers. The last argument of these methods is a Serializable
object whose value becomes part of the Timer
. The Timer's getInfo
method can be used to retrieve this information.
Here, we pass a string to the timer. In the createTimer
method, add the following code to create a timer. The timer is set up to call back the timeout method every 10 seconds. The setInfo
method is passed the string, "information".
scheduleExpression = new ScheduleExpression(); scheduleExpression.second("0/10"); scheduleExpression.minute("*"); scheduleExpression.hour("*"); TimerConfig timerConfig = new TimerConfig(); timerConfig.setInfo("information"); timerService.createCalendarTimer(scheduleExpression,timerConfig);
The memory usage report should be displayed every 10 seconds with the timer data.
In the Single event timers section of the Creating and using programmatic timers recipe, a timer was created using the createTimer
method. Its second argument is an object that implements the Serializable
interface. This object is associated with the timer and can be retrieved by the Timer's getInfo
method.
Replace the SystemReportManager's createTimer
method with the following code. Here, we create a calendar to use with the createTimer
method. Modify the date to reflect a time convenient for you. Next, create an ArrayList
which is initialized with three strings. In this case, they are intended to present font information. Using the createTimer
method, pass the reportDate
and the ArrayList
as its parameters.
public void createTimer() { GregorianCalendar reportCalendar = new GregorianCalendar(2011, Calendar.JANUARY, 6, 19, 56); Date reportDate = reportCalendar.getTime(); ArrayList<String> list = new ArrayList<String>(); list.add("capitalize"); list.add("center"); list.add("arial"); timerService.createTimer(reportDate, list); }
Modify the timeout
method to use the getInfo
method to return a list of strings and then display the list.
@Timeout public void timeout(Timer timer) { ArrayList<String> list = (ArrayList<String>) timer.getInfo(); System.out.println("List Elements"); for(String element : list) { System.out.println(element); } }
When the application is executed your output should display the following:
INFO: List Elements
INFO: capitalize
INFO: center
INFO: arial
3.14.252.56