Mega Code Archive

 
Categories / Java Tutorial / Development
 

Your own timer

/*  * Copyright (c) 1998-2002 Carnegie Mellon University.  All rights  * reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  *  */ import java.util.Vector; public class Timer {     int interval;     boolean periodic;     boolean isExpired = false;     static TimerManager manager = new TimerManager ();     long deadline;     Timer next, prev;     public Timer () {     }     public void set (int msecDelay, boolean periodic) {         interval = msecDelay;         this.periodic = periodic;         isExpired = false;         if (!manager.isAlive ()) {             System.err.println ("TimerManager: restarting");             manager = new TimerManager ();         }         manager.register (this, System.currentTimeMillis () + msecDelay);     }     public int getInterval () {         return interval;     }     public boolean getPeriodic () {         return periodic;     }     public void cancel () {         manager.delete (this);     }     protected void alarm () {     }     public boolean expired () {         return isExpired;     }              /*     public static void main (String[] args) {         for (int i=0; i<args.length; ++i) {             boolean periodic = (args[i].charAt (0) == 'p');             if (periodic) args[i] = args[i].substring (1);             new TestTimer (args[i], Integer.parseInt (args[i]), periodic);         }         while (true) Thread.yield ();     }     */ } class TimerManager extends Thread {     Timer first, last;     /*     static ThreadGroup rootThreadGroup;     static {         rootThreadGroup = Thread.currentThread().getThreadGroup();         while (rootThreadGroup.getParent() != null)             rootThreadGroup = rootThreadGroup.getParent();     }     */     public TimerManager () {         super (/* rootThreadGroup, */ "Timer Manager");         setDaemon (true);         start ();     }     public synchronized void register (Timer t, long deadline) {         t.deadline = deadline;         delete (t);  // just in case it's already registered         //System.err.println ("TimerManager: set " + t + " to go off at " + deadline);       insertion:          {             for (Timer u = first; u != null; u = u.next) {                 if (t.deadline < u.deadline) {                     if (u.prev != null)                         u.prev.next = t;                     else                         first = t;                     t.prev = u.prev;                     t.next = u;                     u.prev = t;                     break insertion;                 }             }             if (last != null) {                 last.next = t;                 t.prev = last;                 t.next = null;                 last = t;             } else {                 first = last = t;             }         }         //System.err.println ("TimerManager: waking up background thread");         notifyAll ();     }     public synchronized void delete (Timer t) {         if (t.next != null)             t.next.prev = t.prev;         if (t.prev != null)             t.prev.next = t.next;         if (t == last)             last = t.prev;         if (t == first)             first = t.next;         t.next = null;         t.prev = null;     }     static final int FOREVER = 60000;  // wake up at least every 60 seconds     public synchronized void run () {         while (true) {             try {                 //System.err.println ("TimerManager: awake");                 if (first == null) {                     //System.err.println ("TimerManager: waiting forever");                     wait (FOREVER);                     //System.err.println ("TimerManager: woke up");                 }                 else {                     Timer t = first;                     long now = System.currentTimeMillis ();                     if (t.deadline <= now) {                         // System.err.println ("TimerManager: timer " + t + " just went off at " + now);                         try {                             t.isExpired = true;                             t.alarm ();                         } catch (Throwable e) {                             if (e instanceof ThreadDeath)                                 throw (ThreadDeath)e;                             else                                 e.printStackTrace ();                         }                         if (t.periodic) {                             register (t, now + t.interval);                         }                         else {                             delete (t);                         }                     }                     else {                         //System.err.println ("TimerManager: waiting for " + (t.deadline - now) + " msec");                         wait (t.deadline - now);                         //System.err.println ("TimerManager: woke up");                     }                 }             } catch (InterruptedException e) {}         }     } } /* class TestTimer extends Timer {     String message;     public TestTimer (String message, int millisec, boolean periodic) {         this.message = message;         set (millisec, periodic);     }     public void alarm () {         System.out.println (message);     } } */