User: simone  
  Date: 00/10/16 16:19:02

  Added:       src/main/org/jboss/util TimerQueue.java
  Log:
  Variant of WorkerQueue that executes TimerTasks
  
  Revision  Changes    Path
  1.1                  jboss/src/main/org/jboss/util/TimerQueue.java
  
  Index: TimerQueue.java
  ===================================================================
  /*
   * jBoss, the OpenSource EJB server
   *
   * Distributable under GPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.util;
  
  /**
   * This class runs in a single thread {@link TimerTask}s that have been 
   * scheduled. <p>
   * A similar class is present in java.util package of jdk version >= 1.3;
   * for compatibility with jdk 1.2 it is reimplemented here.
   *
   * @see TimerTask
   * @author Simone Bordet ([EMAIL PROTECTED])
   * @version $Revision: 1.1 $
   */
  public class TimerQueue 
        extends WorkerQueue
  {
        // Constants -----------------------------------------------------
  
        // Attributes ----------------------------------------------------
        /* This member is accessed only from putJob and getJob, that will 
           then guarantee necessary synchronization on it */
        private Heap m_heap;
  
        // Static --------------------------------------------------------
  
        // Constructors --------------------------------------------------
        /**
         * Creates a new timer queue with default thread name of "TimerTask Thread"
         */
        public TimerQueue() 
        {
                this("TimerTask Thread");
        }
        /**
         * Creates a new timer queue with the specified thread name
         */
        public TimerQueue(String threadName) 
        {
                super(threadName);
                m_heap = new Heap();
        }
  
        // Public --------------------------------------------------------
        /**
         * Schedules the given TimerTask for immediate execution.
         */
        public void schedule(TimerTask t) 
        {
                schedule(t, 0);
        }
        /**
         * Schedule the given TimerTask to be executed after <code>delay</code>
         * milliseconds.
         */
        public void schedule(TimerTask t, long delay) 
        {
                if (t == null) throw new IllegalArgumentException("Can't schedule a 
null TimerTask");
                if (delay < 0) delay = 0;
                t.setNextExecutionTime(System.currentTimeMillis() + delay);
                putJob(t);
        }
  
        // Z implementation ----------------------------------------------
  
        // WorkerQueue overrides ---------------------------------------------------
        protected void putJobImpl(Executable task) 
        {
                m_heap.insert(task);
                ((TimerTask)task).setState(TimerTask.SCHEDULED);
                notifyAll();
        }
        protected Executable getJobImpl() throws InterruptedException
        {
                while (m_heap.peek() == null) 
                {
                        wait();
                }
                TimerTask task = (TimerTask)m_heap.extract();
                switch (task.getState())
                {
                        case TimerTask.CANCELLED:
                        case TimerTask.EXECUTED:
                                return getJobImpl();
                        case TimerTask.NEW:
                        case TimerTask.SCHEDULED:
                                return task;
                        default:
                                throw new IllegalStateException("TimerTask has an 
illegal state");
                }
        }
        protected Runnable createQueueLoop() 
        {
                return new TimerTaskLoop();
        }
        protected void clear() 
        {
                super.clear();
                synchronized (this) 
                {
                        m_heap.clear();
                }
        }
  
        // Package protected ---------------------------------------------
  
        // Protected -----------------------------------------------------
  
        // Private -------------------------------------------------------
  
        // Inner classes -------------------------------------------------
        /**
         * Class that loops getting the next job to be executed and then 
         * executing it, in the timer task thread.
         */
        protected class TimerTaskLoop implements Runnable 
        {
                public void run() 
                {
                        try
                        {
                                while (true) 
                                {
                                        try 
                                        {
                                                // Wait for the first job
                                                TimerTask task = (TimerTask)getJob();
                                                long now = System.currentTimeMillis();
                                                long executionTime = 
task.getNextExecutionTime();
                                                long timeToWait = executionTime - now;
                                                boolean runTask = timeToWait <= 0;
                                                if (!runTask)
                                                {
                                                        // Entering here when a new 
job is scheduled but
                                                        // it's not yet time to run 
the first one;
                                                        // the job was extracted from 
the heap, reschedule
                                                        putJob(task);
                                                        Object mutex = TimerQueue.this;
                                                        synchronized (mutex)
                                                        {
                                                                // timeToWait is 
always strictly > 0, so I don't wait forever
                                                                mutex.wait(timeToWait);
                                                        }
                                                }
                                                else
                                                {
                                                        if (task.isPeriodic())
                                                        {
                                                                // Reschedule with the 
new time
                                                                
task.setNextExecutionTime(executionTime + task.getPeriod());
                                                                putJob(task);
                                                        }
                                                        else
                                                        {
                                                                // The one-shot task 
is already removed from 
                                                                // the heap, mark it 
as executed
                                                                
task.setState(TimerTask.EXECUTED);
                                                        }
                                                        // Run it !
                                                        task.execute();
                                                }
                                        }
                                        catch (InterruptedException x)
                                        {
                                                // Exit the thread
                                                break;
                                        }
                                        catch (Exception x)
                                        {
                                                x.printStackTrace();
                                                // and go on with the next job
                                        }
                                }
                        }
                        finally {clear();}
                }
        }
  }
  
  
  

Reply via email to