在Jotm中看到一個(gè)很齊全的定時(shí)器,貼出來(lái)以防備用;
package org.objectweb.jotm;
import java.util.Vector;
/**
*
*對(duì)計(jì)時(shí)器列表中的計(jì)時(shí)器進(jìn)行倒計(jì)時(shí)
*/
class Clock extends Thread {
private TimerManager tmgr;
public Clock(TimerManager tmgr) {
super("JotmClock");
if (TraceTm.jta.isDebugEnabled()) {
TraceTm.jta.debug("Clock constructor");
}
this.tmgr = tmgr;
}
public void run() {
tmgr.clock();
}
}
/**
*
*Examda提示:出去計(jì)時(shí)器列表中的過(guò)期計(jì)時(shí)器,如倒計(jì)時(shí)為負(fù)數(shù)
*/
class Batch extends Thread {
private TimerManager tmgr;
public Batch(TimerManager tmgr) {
super("JotmBatch");
if (TraceTm.jta.isDebugEnabled()) {
TraceTm.jta.debug("Batch constructor");
}
this.tmgr = tmgr;
}
public void run() {
tmgr.batch();
}
}
/**
*含有兩個(gè)計(jì)時(shí)器列表,并且含有兩個(gè)線程,一個(gè)線程進(jìn)行計(jì)時(shí)器的倒計(jì)時(shí),
*一個(gè)線程移除過(guò)期計(jì)時(shí)器并且執(zhí)行計(jì)時(shí)器的監(jiān)聽器動(dòng)作;
*/
public class TimerManager {
// threads managing the service.
private static Batch batchThread;
private static Clock clockThread;
// lists
//計(jì)時(shí)器列表
private Vector timerList = new Vector();
//過(guò)期計(jì)時(shí)器列表
private Vector expiredList = new Vector();
//單例
private static TimerManager unique = null;
private static boolean shuttingdown = false;
/**
* Constructor
*/
private TimerManager() {
// launch threads for timers
batchThread = new Batch(this);
batchThread.setDaemon(true);
batchThread.start();
clockThread = new Clock(this);
clockThread.setDaemon(true);
clockThread.start();
}
/**
* 這個(gè)時(shí)間管理器是一個(gè)單例類;
*/
public static TimerManager getInstance() {
if (unique == null)
unique = new TimerManager();
return unique;
}
//停止時(shí)間管理器中的計(jì)時(shí)器;
public static void stop(boolean force) {
if (TraceTm.jta.isDebugEnabled()) {
TraceTm.jta.debug("Stop TimerManager");
}
TimerManager tmgr = getInstance();
shuttingdown = true;
while (clockThread.isAlive() || batchThread.isAlive()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
break;
}
}
if (TraceTm.jta.isDebugEnabled()) {
TraceTm.jta.debug("TimerManager has stopped");
}
}
public static void stop() {
stop(true);
}
/**
* cney speed up the clock x1000 when shutting down
* update all timers in the list
* each timer expired is put in a special list of expired timers
* they will be processed then by the Batch Thread.
*/ public void clock() {
//無(wú)限循環(huán)
while (true) {
try {
//線程休息一秒
Thread.sleep(shuttingdown?1:1000); // 1 second or 1ms shen shuttingdown
// Thread.currentThread().sleep(shuttingdown?1:1000); // 1 second or 1ms shen shuttingdown
synchronized(timerList) {
int found = 0;
boolean empty = true;
for (int i = 0; i < timerList.size(); i++) {
TimerEvent t = (TimerEvent) timerList.elementAt(i);
//如果沒有活動(dòng)的計(jì)時(shí)器,那么計(jì)時(shí)器隊(duì)列為空;
if (!t.isStopped()) {
empty = false;
}
//如果計(jì)時(shí)器過(guò)期
if (t.update() <= 0) {
//從計(jì)時(shí)器隊(duì)列中移除
timerList.removeElementAt(i--);
if (t.valid()) {
//該計(jì)時(shí)器存在計(jì)時(shí)器監(jiān)聽器的話,把這個(gè)計(jì)時(shí)器加入過(guò)期計(jì)時(shí)器
//如果不存在,則廢除,哪個(gè)隊(duì)列都不加入
expiredList.addElement(t);
found++;
//如果持續(xù)的話,則繼續(xù)把該計(jì)時(shí)器再次加入計(jì)時(shí)器隊(duì)列中
if (t.ispermanent() && !shuttingdown) {
t.restart();
timerList.addElement(t);
}
}
}
// Be sure there is no more ref on bean in this local variable.
t = null;
}
if (found > 0) {
//喚醒線程;
timerList.notify();
} else {
if (empty && shuttingdown) {
break;
}
}
}
} catch (InterruptedException e) {
TraceTm.jta.error("Timer interrupted");
}
}
synchronized(timerList) { // notify batch so that function can return.
timerList.notify();
}
}
/**
* process all expired timers
*/
public void batch() {
while (!(shuttingdown && timerList.isEmpty() && expiredList.isEmpty())) {
TimerEvent t;
synchronized(timerList) {
while (expiredList.isEmpty()) {
if (shuttingdown) return;
try {
//計(jì)時(shí)器計(jì)時(shí)線程讓如果找到到期的計(jì)時(shí)器,那么就會(huì)喚醒執(zhí)行該計(jì)時(shí)器的線程執(zhí)行監(jiān)聽器動(dòng)作
timerList.wait();
} catch (Exception e) {
TraceTm.jta.error("Exception in Batch: ", e);
}
}
t = (TimerEvent) expiredList.elementAt(0);
expiredList.removeElementAt(0);
}
//執(zhí)行動(dòng)作;
t.process();
}
}
/**
* add a new timer in the list
* @param tel Object that will be notified when the timer expire.
* @param timeout nb of seconds before the timer expires.
* @param arg info passed with the timer
* @param permanent true if the timer is permanent.
*/
public TimerEvent addTimer(TimerEventListener tel, long timeout, Object arg, boolean permanent) {
TimerEvent te = new TimerEvent(tel, timeout, arg, permanent);
synchronized(timerList) {
timerList.addElement(te);
}
return te;
}
/**
* remove a timer from the list. this is not very efficient.
* A better way to do this is TimerEvent.unset()
* @deprecated
*/
public void removeTimer(TimerEvent te) {
synchronized(timerList) {
timerList.removeElement(te);
}
}
}
package org.objectweb.jotm;
import java.util.Vector;
/**
*
*對(duì)計(jì)時(shí)器列表中的計(jì)時(shí)器進(jìn)行倒計(jì)時(shí)
*/
class Clock extends Thread {
private TimerManager tmgr;
public Clock(TimerManager tmgr) {
super("JotmClock");
if (TraceTm.jta.isDebugEnabled()) {
TraceTm.jta.debug("Clock constructor");
}
this.tmgr = tmgr;
}
public void run() {
tmgr.clock();
}
}
/**
*
*Examda提示:出去計(jì)時(shí)器列表中的過(guò)期計(jì)時(shí)器,如倒計(jì)時(shí)為負(fù)數(shù)
*/
class Batch extends Thread {
private TimerManager tmgr;
public Batch(TimerManager tmgr) {
super("JotmBatch");
if (TraceTm.jta.isDebugEnabled()) {
TraceTm.jta.debug("Batch constructor");
}
this.tmgr = tmgr;
}
public void run() {
tmgr.batch();
}
}
/**
*含有兩個(gè)計(jì)時(shí)器列表,并且含有兩個(gè)線程,一個(gè)線程進(jìn)行計(jì)時(shí)器的倒計(jì)時(shí),
*一個(gè)線程移除過(guò)期計(jì)時(shí)器并且執(zhí)行計(jì)時(shí)器的監(jiān)聽器動(dòng)作;
*/
public class TimerManager {
// threads managing the service.
private static Batch batchThread;
private static Clock clockThread;
// lists
//計(jì)時(shí)器列表
private Vector timerList = new Vector();
//過(guò)期計(jì)時(shí)器列表
private Vector expiredList = new Vector();
//單例
private static TimerManager unique = null;
private static boolean shuttingdown = false;
/**
* Constructor
*/
private TimerManager() {
// launch threads for timers
batchThread = new Batch(this);
batchThread.setDaemon(true);
batchThread.start();
clockThread = new Clock(this);
clockThread.setDaemon(true);
clockThread.start();
}
/**
* 這個(gè)時(shí)間管理器是一個(gè)單例類;
*/
public static TimerManager getInstance() {
if (unique == null)
unique = new TimerManager();
return unique;
}
//停止時(shí)間管理器中的計(jì)時(shí)器;
public static void stop(boolean force) {
if (TraceTm.jta.isDebugEnabled()) {
TraceTm.jta.debug("Stop TimerManager");
}
TimerManager tmgr = getInstance();
shuttingdown = true;
while (clockThread.isAlive() || batchThread.isAlive()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
break;
}
}
if (TraceTm.jta.isDebugEnabled()) {
TraceTm.jta.debug("TimerManager has stopped");
}
}
public static void stop() {
stop(true);
}
/**
* cney speed up the clock x1000 when shutting down
* update all timers in the list
* each timer expired is put in a special list of expired timers
* they will be processed then by the Batch Thread.
*/ public void clock() {
//無(wú)限循環(huán)
while (true) {
try {
//線程休息一秒
Thread.sleep(shuttingdown?1:1000); // 1 second or 1ms shen shuttingdown
// Thread.currentThread().sleep(shuttingdown?1:1000); // 1 second or 1ms shen shuttingdown
synchronized(timerList) {
int found = 0;
boolean empty = true;
for (int i = 0; i < timerList.size(); i++) {
TimerEvent t = (TimerEvent) timerList.elementAt(i);
//如果沒有活動(dòng)的計(jì)時(shí)器,那么計(jì)時(shí)器隊(duì)列為空;
if (!t.isStopped()) {
empty = false;
}
//如果計(jì)時(shí)器過(guò)期
if (t.update() <= 0) {
//從計(jì)時(shí)器隊(duì)列中移除
timerList.removeElementAt(i--);
if (t.valid()) {
//該計(jì)時(shí)器存在計(jì)時(shí)器監(jiān)聽器的話,把這個(gè)計(jì)時(shí)器加入過(guò)期計(jì)時(shí)器
//如果不存在,則廢除,哪個(gè)隊(duì)列都不加入
expiredList.addElement(t);
found++;
//如果持續(xù)的話,則繼續(xù)把該計(jì)時(shí)器再次加入計(jì)時(shí)器隊(duì)列中
if (t.ispermanent() && !shuttingdown) {
t.restart();
timerList.addElement(t);
}
}
}
// Be sure there is no more ref on bean in this local variable.
t = null;
}
if (found > 0) {
//喚醒線程;
timerList.notify();
} else {
if (empty && shuttingdown) {
break;
}
}
}
} catch (InterruptedException e) {
TraceTm.jta.error("Timer interrupted");
}
}
synchronized(timerList) { // notify batch so that function can return.
timerList.notify();
}
}
/**
* process all expired timers
*/
public void batch() {
while (!(shuttingdown && timerList.isEmpty() && expiredList.isEmpty())) {
TimerEvent t;
synchronized(timerList) {
while (expiredList.isEmpty()) {
if (shuttingdown) return;
try {
//計(jì)時(shí)器計(jì)時(shí)線程讓如果找到到期的計(jì)時(shí)器,那么就會(huì)喚醒執(zhí)行該計(jì)時(shí)器的線程執(zhí)行監(jiān)聽器動(dòng)作
timerList.wait();
} catch (Exception e) {
TraceTm.jta.error("Exception in Batch: ", e);
}
}
t = (TimerEvent) expiredList.elementAt(0);
expiredList.removeElementAt(0);
}
//執(zhí)行動(dòng)作;
t.process();
}
}
/**
* add a new timer in the list
* @param tel Object that will be notified when the timer expire.
* @param timeout nb of seconds before the timer expires.
* @param arg info passed with the timer
* @param permanent true if the timer is permanent.
*/
public TimerEvent addTimer(TimerEventListener tel, long timeout, Object arg, boolean permanent) {
TimerEvent te = new TimerEvent(tel, timeout, arg, permanent);
synchronized(timerList) {
timerList.addElement(te);
}
return te;
}
/**
* remove a timer from the list. this is not very efficient.
* A better way to do this is TimerEvent.unset()
* @deprecated
*/
public void removeTimer(TimerEvent te) {
synchronized(timerList) {
timerList.removeElement(te);
}
}
}