One shot timers are used to generate a single timed event a specific period of time after the timed event was requested. There are no constraints over which thread actually issues the request, so it is perfectly legitimate to request a timed event from the main application thread, as shown in Listing 3.3. This code is present in the timer examples package as OneShotTimerExample1.
The example shown in Listing 3.3 uses the timed callback to shut down the reactor after a specific amount of time. The reactor startup code is identical to that previously described in Section 2.5. However, rather than issuing the reactor stop request from the main thread it is instead implemented within a timeable callback.
In order for the timeable callback to issue the reactor stop request it must have a handle on the reactor's control interface. In the example this is passed as the timer's data parameter. The data parameter is an opaque object reference which is held by the timer and then passed on to the timeable callback once the timer has expired. Any arbitrary object data may be passed in this manner, but it is obviously important when documenting timeable callback classes to explicitly state the types of object which are supported.
In the event that a data parameter object of an incompatible type is passed to a timeable callback an exception will be thrown. All exceptions thrown by timeable callbacks are caught by the reaction framework and will be logged with a log level of warning. The continued operation of the reactor is unaffected. In the example, the second timer request passes an incompatible data parameter and will therefore generate an exception.
One thing which must be taken into account when using timers is that the specified delay must be treated as a minimum delay parameter. This is because the timer callback will be issued an arbitrary - but usually small - time after the delay period has expired. This delay may be caused by underlying operating system context switches, Java thread scheduling artifacts or long-running callbacks which are active at the point when the delay period expires. Figure 3.1 shows the delay in issuing callbacks relative to the fixed reactor timebase.