User: ejort Date: 02/04/20 04:37:49 Modified: src/main/javax/management/timer Timer.java Log: Improved Timer and Monitor Services Revision Changes Path 1.9 +35 -173 jmx/src/main/javax/management/timer/Timer.java Index: Timer.java =================================================================== RCS file: /cvsroot/jboss/jmx/src/main/javax/management/timer/Timer.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- Timer.java 14 Apr 2002 15:23:00 -0000 1.8 +++ Timer.java 20 Apr 2002 11:37:49 -0000 1.9 @@ -19,13 +19,14 @@ import javax.management.NotificationBroadcasterSupport; import javax.management.ObjectName; -import org.jboss.mx.util.ThreadPool; +import org.jboss.mx.util.RunnableScheduler; +import org.jboss.mx.util.SchedulableRunnable; /** * The timer service. * * @author <a href="mailto:[EMAIL PROTECTED]">Adrian Brock</a> - * @version $Revision: 1.8 $ + * @version $Revision: 1.9 $ */ public class Timer extends NotificationBroadcasterSupport @@ -106,14 +107,9 @@ HashMap notifications = new HashMap(); /** - * The controlling thread + * The scheduler */ - private Controller controller = new Controller(); - - /** - * The date next run of the notifications, zero when nothing to run. - */ - long nextRunDate = 0; + private RunnableScheduler scheduler = new RunnableScheduler(); // Static -------------------------------------------------------- @@ -155,9 +151,7 @@ synchronized(notifications) { notifications.put(id, rn); - - // Work out if this is the next to run - reschedule(rn, true); + rn.setScheduler(scheduler); } return id; @@ -281,11 +275,20 @@ // Remove the notifications synchronized(notifications) { - notifications.clear(); + Iterator iterator = notifications.values().iterator(); + while (iterator.hasNext()) + { + RegisteredNotification rn = (RegisteredNotification) iterator.next(); + rn.setScheduler(null); + iterator.remove(); + } } // The spec says to reset the identifiers, seems like a bad idea to me - nextId = 0; + synchronized (this) + { + nextId = 0; + } } public void removeNotification(Integer id) @@ -300,6 +303,7 @@ id.toString()); // Remove the notification + rn.setScheduler(null); notifications.remove(id); } } @@ -318,6 +322,7 @@ RegisteredNotification rn = (RegisteredNotification) iterator.next(); if (rn.type.equals(type)) { + rn.setScheduler(null); iterator.remove(); found = true; } @@ -359,8 +364,8 @@ } } - // Start the controlling thread - controller.start(); + // Start 'em up + scheduler.start(); } public synchronized void stop() @@ -371,7 +376,7 @@ // Stop the threads active = false; - controller.cancel(); + scheduler.stop(); } // MBeanRegistrationImplementation overrides --------------------- @@ -408,46 +413,6 @@ // Private ------------------------------------------------------- /** - * Recalculate the next run for inactive notifications. - */ - private void reschedule() - { - // No need to reschedule when not active - if (isActive() == false) - return; - - nextRunDate = 0; - - // Loop through the registered notifications to find the next run. - Iterator iterator = notifications.values().iterator(); - while (iterator.hasNext()) - { - RegisteredNotification rn = (RegisteredNotification) iterator.next(); - if (rn.running == false) - reschedule(rn, false); - } - } - - /** - * See whether this notification is the next one. - * - * @param rn the notification to check - * @param notify whether to notify the controller of changes - */ - private void reschedule(RegisteredNotification rn, boolean notify) - { - synchronized (notifications) - { - if (nextRunDate == 0 || rn.nextDate < nextRunDate) - { - nextRunDate = rn.nextDate; - if (notify == true) - notifications.notify(); - } - } - } - - /** * Send any outstanding notifications. * * @param rn the registered notification to send. @@ -467,7 +432,11 @@ // Yes, unless start and not sending past notifications. if (rn.sendType != SEND_NO) { - long seq = ++sequenceNumber; + long seq = 0; + synchronized(this) + { + seq = ++sequenceNumber; + } sendNotification(new TimerNotification(rn.type, objectName, seq, rn.nextDate, rn.message, rn.id, rn.userData)); } @@ -490,11 +459,8 @@ && rn.occurences == 0 && rn.nextDate < System.currentTimeMillis()); } - // We've finished with this notification - rn.running = false; - - // Work out if this is the next to run - reschedule(rn, true); + if (rn.nextDate != 0) + rn.setNextRun(rn.nextDate); } // Inner classes ------------------------------------------------- @@ -503,7 +469,7 @@ * A registered notification. These run as separate threads. */ private class RegisteredNotification - implements Runnable + extends SchedulableRunnable { // Attributes ---------------------------------------------------- @@ -543,19 +509,14 @@ public long occurences; /** - * The next notification date. - */ - public long nextDate; - - /** * The send type, no send, past notifications or normal */ public int sendType = SEND_NORMAL; /** - * Whether we are already in a notification + * The next run date */ - public boolean running = false; + public long nextDate = 0; // Constructors -------------------------------------------------- @@ -617,7 +578,7 @@ * * @return false when there are no more occurences, true otherwise. */ - synchronized boolean calcNextDate() + boolean calcNextDate() { // No period, we've finished if (period == 0) @@ -639,114 +600,15 @@ return true; } - // Runnable overrides ------------------------------------------- + // SchedulableRunnable overrides --------------------------------- /** * Send the notifications. */ - public void run() + public void doRun() { // Send any notifications sendNotifications(this); - } - } - - /** - * The controlling thread. - */ - private class Controller - extends Thread - { - // Attributes ---------------------------------------------------- - - /** - * The thread pool used to obtain threads to send the notifications. - */ - ThreadPool threadPool; - - // Constructors -------------------------------------------------- - - /** - * This controller runs in a different thread as a daemon. - * It has a thread pool to run notifications. - */ - public Controller() - { - super(); - setDaemon(true); - threadPool = new ThreadPool(); - } - - // Public -------------------------------------------------------- - - /** - * Start the thread pool, before starting this thread - */ - public void start() - { - threadPool.setActive(true); - super.start(); - } - - /** - * Stop the thread pool, don't stop the thread - */ - public void cancel() - { - threadPool.setActive(false); - } - - /** - * Wait until the next run date or until we are interrupted by - * a reschedule. When active, check the registered notifications - * to see whether notifications should be sent. - */ - public void run() - { - // Keep going until we are stopped - while (isActive()) - { - synchronized(notifications) - { - // Run any due notifications - Iterator iterator = notifications.values().iterator(); - while (iterator.hasNext()) - { - RegisteredNotification rn = (RegisteredNotification) iterator.next(); - - // Notification required - if (isActive() && rn.running == false - && rn.nextDate <= System.currentTimeMillis()) - { - rn.running = true; - threadPool.run(rn); - } - } - } - - synchronized(notifications) - { - // Reschedule the inactive notifications - reschedule(); - - // Wait until the next run or we are interrupted - if (isActive()) - { - try - { - if (nextRunDate == 0) - notifications.wait(999999); - else - { - long waitMillis = nextRunDate - System.currentTimeMillis(); - if (waitMillis > 0) - notifications.wait(waitMillis); - } - } - catch (InterruptedException ignored) {} - } - } - } } } }
_______________________________________________ Jboss-development mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/jboss-development