Notification Types
There are two types of notifications offered by the Timer service:
The Timer service schedules events in a separate thread. When the time to notify a timer listener comes, the Timer service gets a thread from the pool and performs the notification.
No-Delay Timers
As Timer service uses the Thread Pool Manager for execution of timer notifications, it can allocate no more than 30 percent of the thread pool's capacity. This suggests that some notifications may be done later than requested. Mostly, it is considered that it is important to be notified in some time and accuracy is not an issue. But there are cases when it is critical to be notified on time. To answer the needs of critical notifications, the Timer service allows bundles to specify that notification must be as close to the time of the event as possible by adding timers of type no-delay. Such timers are executed in newly created threads if the thread pool does not provide enough free ones.
Registering for Notification
To use the Timer service, the other bundles have to get it. The Timer service interface is com.prosyst.util.timer.Timer. The BundleContext.getService(org.osgi.framework.ServiceReference) method will return a single instance of the Timer service that is associated only with the used bundle context.
To register for notification, the calling bundle must supply a com.prosyst.util.timer.TimerListener object to the Timer by invoking Timer's addNotifyListener method. Each timer listener should specify:
As a result a TimerListener associated with a timer of a given notification type, a given event and a given time period should be registered in the Timer service event queue. When the TimerListener associated time period expires, the Timer service invokes the corresponding listener's TimerListener.timer(int) with the specified event. If the timer listener's timerType is ONE_SHOT_TIMER or ONE_SHOT_TIMER_NO_DELAY, the Timer service removes it from the event queue.
If the addNotifyListener(TimerListener, int, int, long, int) method is invoked with listener and event parameters that already exist in the queue, the previous listener is removed and the new one replaces it, no matter if the time period has expired or not.
If more than one timers are started with the same listener and different events, the event shows which of them notifies the listener.
With the removeListener(TimerListener, int) method it is possible to unregister a listener with the specified event from the queue before its time period has expired. If the listener with the specified event is not found, nothing happens.
For more details and examples refer to the Java API.
The following example shows a timer listener, which subscribes to both one-shot and periodical time events.
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import com.prosyst.util.timer.Timer;
import com.prosyst.util.timer.TimerListener;
public class MyTimerListener implements BundleActivator, TimerListener{
private ServiceReference refTimer = null;
private Timer timer = null;
final static String SERVICE_TIMER = Timer.class.getName();
static final int EVENT_TYPE_1 = 1;
static final int EVENT_TYPE_2 = 2;
int type2Counter;
public void start(BundleContext bc) throws Exception {
try {
refTimer = bc.getServiceReference(SERVICE_TIMER);
if (refTimer != null) {
timer = (Timer)bc.getService(refTimer);
timer.addNotifyListener(this,
Thread.MIN_PRIORITY,
Timer.ONE_SHOT_TIMER,
(long)100,
EVENT_TYPE_1);
timer.addNotifyListener(this,
Thread.NORM_PRIORITY,
Timer.PERIODICAL_TIMER,
(long)1000,
EVENT_TYPE_2);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void stop(BundleContext bc) throws Exception {
if (refTimer != null) {
timer.removeListener(this, EVENT_TYPE_1);
timer.removeListener(this, EVENT_TYPE_2);
bc.ungetService(refTimer);
}
}
public void timer(int event) {
if(event == EVENT_TYPE_1){
System.out.println("Event of type 1 received!");
} else if( event == EVENT_TYPE_2) {
if(type2Counter < 10) {
System.out.println("Event of type 2 received!");
type2Counter++;
} else {
timer.removeListener(this, EVENT_TYPE_2);
}
}
}
}
System Properties
To specify the priority of the thread scheduling timer events refer to the Setup Guide.
References