User: ejort Date: 02/04/14 08:23:00 Modified: src/main/javax/management/timer Timer.java Log: A timer service that doesn't busy wait Revision Changes Path 1.8 +102 -73 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.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- Timer.java 14 Apr 2002 02:58:43 -0000 1.7 +++ Timer.java 14 Apr 2002 15:23:00 -0000 1.8 @@ -9,6 +9,7 @@ import java.io.Serializable; import java.util.Date; +import java.util.HashMap; import java.util.Iterator; import java.util.Vector; @@ -18,15 +19,13 @@ import javax.management.NotificationBroadcasterSupport; import javax.management.ObjectName; -import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap; - import org.jboss.mx.util.ThreadPool; /** * The timer service. * * @author <a href="mailto:[EMAIL PROTECTED]">Adrian Brock</a> - * @version $Revision: 1.7 $ + * @version $Revision: 1.8 $ */ public class Timer extends NotificationBroadcasterSupport @@ -104,7 +103,7 @@ /** * The registered notifications. */ - ConcurrentReaderHashMap notifications = new ConcurrentReaderHashMap(); + HashMap notifications = new HashMap(); /** * The controlling thread @@ -153,17 +152,23 @@ occurences); // Add the registration. - notifications.put(id, rn); + synchronized(notifications) + { + notifications.put(id, rn); - // Work out if this is the next to run - reschedule(rn, true); + // Work out if this is the next to run + reschedule(rn, true); + } return id; } public Vector getAllNotificationIDs() { - return new Vector(notifications.keySet()); + synchronized(notifications) + { + return new Vector(notifications.keySet()); + } } public Date getDate(Integer id) @@ -198,12 +203,15 @@ Vector result = new Vector(); // Loop through the notifications looking for the passed type. - Iterator iterator = notifications.values().iterator(); - while (iterator.hasNext()) + synchronized (notifications) { - RegisteredNotification rn = (RegisteredNotification) iterator.next(); - if (rn.type.equals(type)) - result.add(rn.id); + Iterator iterator = notifications.values().iterator(); + while (iterator.hasNext()) + { + RegisteredNotification rn = (RegisteredNotification) iterator.next(); + if (rn.type.equals(type)) + result.add(rn.id); + } } return result; @@ -271,7 +279,10 @@ public void removeAllNotifications() { // Remove the notifications - notifications.clear(); + synchronized(notifications) + { + notifications.clear(); + } // The spec says to reset the identifiers, seems like a bad idea to me nextId = 0; @@ -281,13 +292,16 @@ throws InstanceNotFoundException { // Check if there is a notification. - RegisteredNotification rn = (RegisteredNotification) notifications.get(id); - if (rn == null) - throw new InstanceNotFoundException("No notification id : " + + synchronized(notifications) + { + RegisteredNotification rn = (RegisteredNotification) notifications.get(id); + if (rn == null) + throw new InstanceNotFoundException("No notification id : " + id.toString()); - // Remove the notification - notifications.remove(id); + // Remove the notification + notifications.remove(id); + } } public void removeNotifications(String type) @@ -296,15 +310,18 @@ boolean found = false; // Loop through the notifications removing the passed type. - Iterator iterator = notifications.values().iterator(); - while (iterator.hasNext()) + synchronized(notifications) { - RegisteredNotification rn = (RegisteredNotification) iterator.next(); - if (rn.type.equals(type)) - { - iterator.remove(); - found = true; - } + Iterator iterator = notifications.values().iterator(); + while (iterator.hasNext()) + { + RegisteredNotification rn = (RegisteredNotification) iterator.next(); + if (rn.type.equals(type)) + { + iterator.remove(); + found = true; + } + } } // The spec says to through an exception when nothing removed. @@ -327,16 +344,19 @@ // Perform the initial sends, for past notifications send missed events // otherwise ignore them - Iterator iterator = notifications.values().iterator(); - while (iterator.hasNext()) + synchronized(notifications) { - RegisteredNotification rn = (RegisteredNotification) iterator.next(); - if (sendPastNotifications) - rn.sendType = SEND_START; - else - rn.sendType = SEND_NO; - sendNotifications(rn); - rn.sendType = SEND_NORMAL; + Iterator iterator = notifications.values().iterator(); + while (iterator.hasNext()) + { + RegisteredNotification rn = (RegisteredNotification) iterator.next(); + if (sendPastNotifications) + rn.sendType = SEND_START; + else + rn.sendType = SEND_NO; + sendNotifications(rn); + rn.sendType = SEND_NORMAL; + } } // Start the controlling thread @@ -416,13 +436,13 @@ */ private void reschedule(RegisteredNotification rn, boolean notify) { - synchronized (this) + synchronized (notifications) { if (nextRunDate == 0 || rn.nextDate < nextRunDate) { nextRunDate = rn.nextDate; if (notify == true) - controller.interrupt(); + notifications.notify(); } } } @@ -460,7 +480,10 @@ // If no next run, remove it sets the next date to zero. if (rn.calcNextDate() == false) { - notifications.remove(rn.id); + synchronized(notifications) + { + notifications.remove(rn.id); + } } } while (isActive() == true && rn.sendType != SEND_START && rn.nextDate != 0 @@ -680,44 +703,50 @@ */ public void run() { - // Keep going until we are stopped - while (isActive()) - { - // 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()) + // Keep going until we are stopped + while (isActive()) + { + synchronized(notifications) { - rn.running = true; - threadPool.run(rn); + // 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); + } + } } - } - // Reschedule the inactive notifications - reschedule(); - - // Wait until the next run or we are interrupted - if (isActive()) - { - try + synchronized(notifications) { - if (nextRunDate == 0) - sleep(10); - else - { - long waitMillis = nextRunDate - System.currentTimeMillis(); - if (waitMillis > 0) - sleep(waitMillis); - } - } - catch (InterruptedException ignored) {} - } - } + // 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