KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > util > TimerQueue


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.util;
23
24 /**
25  * This class runs in a single thread {@link TimerTask}s that have been
26  * scheduled. <p>
27  * A similar class is present in java.util package of jdk version >= 1.3;
28  * for compatibility with jdk 1.2 it is reimplemented here.
29  *
30  * @see TimerTask
31  * @author <a HREF="mailto:simone.bordet@compaq.com">Simone Bordet</a>
32  * @version $Revision: 1958 $
33  */

34 public class TimerQueue
35    extends WorkerQueue
36 {
37    // Constants -----------------------------------------------------
38

39    // Attributes ----------------------------------------------------
40
/* This member is accessed only from putJob and getJob, that will
41       then guarantee necessary synchronization on it */

42    private Heap m_heap;
43
44    // Static --------------------------------------------------------
45

46    // Constructors --------------------------------------------------
47
/**
48     * Creates a new timer queue with default thread name of "TimerTask Thread"
49     */

50    public TimerQueue()
51    {
52       this("TimerTask Thread");
53    }
54    /**
55     * Creates a new timer queue with the specified thread name
56     */

57    public TimerQueue(String JavaDoc threadName)
58    {
59       super(threadName);
60       m_heap = new Heap();
61    }
62
63    // Public --------------------------------------------------------
64
/**
65     * Schedules the given TimerTask for immediate execution.
66     */

67    public void schedule(TimerTask t)
68    {
69       schedule(t, 0);
70    }
71    /**
72     * Schedule the given TimerTask to be executed after <code>delay</code>
73     * milliseconds.
74     */

75    public void schedule(TimerTask t, long delay)
76    {
77       if (t == null) throw new IllegalArgumentException JavaDoc("Can't schedule a null TimerTask");
78       if (delay < 0) delay = 0;
79       t.setNextExecutionTime(System.currentTimeMillis() + delay);
80       putJob(t);
81    }
82
83    // Z implementation ----------------------------------------------
84

85    // WorkerQueue overrides ---------------------------------------------------
86
protected void putJobImpl(Executable task)
87    {
88       m_heap.insert(task);
89       ((TimerTask)task).setState(TimerTask.SCHEDULED);
90       notifyAll();
91    }
92    protected Executable getJobImpl() throws InterruptedException JavaDoc
93    {
94       while (m_heap.peek() == null)
95       {
96          wait();
97       }
98       TimerTask task = (TimerTask)m_heap.extract();
99       switch (task.getState())
100       {
101        case TimerTask.CANCELLED:
102        case TimerTask.EXECUTED:
103           //don't hold onto last dead task if we wait.
104
task = null;
105           return getJobImpl();
106        case TimerTask.NEW:
107        case TimerTask.SCHEDULED:
108           return task;
109        default:
110           throw new IllegalStateException JavaDoc("TimerTask has an illegal state");
111       }
112    }
113    protected Runnable JavaDoc createQueueLoop()
114    {
115       return new TimerTaskLoop();
116    }
117    protected void clear()
118    {
119       super.clear();
120       synchronized (this)
121       {
122          m_heap.clear();
123       }
124    }
125
126    // Package protected ---------------------------------------------
127

128    // Protected -----------------------------------------------------
129

130    // Private -------------------------------------------------------
131

132    // Inner classes -------------------------------------------------
133
/**
134     * Class that loops getting the next job to be executed and then
135     * executing it, in the timer task thread.
136     */

137    protected class TimerTaskLoop implements Runnable JavaDoc
138    {
139       public void run()
140       {
141          try
142          {
143             while (true)
144             {
145                try
146                {
147                   // Wait for the first job
148
TimerTask task = (TimerTask)getJob();
149                   long now = System.currentTimeMillis();
150                   long executionTime = task.getNextExecutionTime();
151                   long timeToWait = executionTime - now;
152                   boolean runTask = timeToWait <= 0;
153                   if (!runTask)
154                   {
155                      // Entering here when a new job is scheduled but
156
// it's not yet time to run the first one;
157
// the job was extracted from the heap, reschedule
158
putJob(task);
159                      Object JavaDoc mutex = TimerQueue.this;
160                      synchronized (mutex)
161                      {
162                         // timeToWait is always strictly > 0, so I don't wait forever
163
mutex.wait(timeToWait);
164                      }
165                   }
166                   else
167                   {
168                      if (task.isPeriodic())
169                      {
170                         // Reschedule with the new time
171
task.setNextExecutionTime(executionTime + task.getPeriod());
172                         putJob(task);
173                      }
174                      else
175                      {
176                         // The one-shot task is already removed from
177
// the heap, mark it as executed
178
task.setState(TimerTask.EXECUTED);
179                      }
180                      // Run it !
181
task.execute();
182                   }
183                }
184                catch (InterruptedException JavaDoc x)
185                {
186                   // Exit the thread
187
break;
188                }
189                catch (Exception JavaDoc e)
190                {
191                   ThrowableHandler.add(ThrowableHandler.Type.ERROR, e);
192                }
193             }
194          }
195          finally {clear();}
196       }
197    }
198 }
199
Popular Tags