Source Code Cross Referenced for ClockDaemon.java in  » Ajax » Laszlo-4.0.10 » EDU » oswego » cs » dl » util » concurrent » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » Laszlo 4.0.10 » EDU.oswego.cs.dl.util.concurrent 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:          File: ClockDaemon.java
003:
004:          Originally written by Doug Lea and released into the public domain.
005:          This may be used for any purposes whatsoever without acknowledgment.
006:          Thanks for the assistance and support of Sun Microsystems Labs,
007:          and everyone contributing, testing, and using this code.
008:
009:          History:
010:          Date       Who                What
011:          29Aug1998  dl               created initial public version
012:          17dec1998  dl               null out thread after shutdown
013:         */
014:
015:        package EDU.oswego.cs.dl.util.concurrent;
016:
017:        import java.util.Comparator;
018:        import java.util.Date;
019:
020:        /**
021:         * A general-purpose time-based daemon, vaguely similar in functionality
022:         * to common system-level utilities such as <code>at</code> 
023:         * (and the associated crond) in Unix.
024:         * Objects of this class maintain a single thread and a task queue
025:         * that may be used to execute Runnable commands in any of three modes --
026:         * absolute (run at a given time), relative (run after a given delay),
027:         * and periodic (cyclically run with a given delay).
028:         * <p>
029:         * All commands are executed by the single background thread. 
030:         * The thread is not actually started until the first 
031:         * request is encountered. Also, if the
032:         * thread is stopped for any reason, one is started upon encountering
033:         * the next request,  or <code>restart()</code> is invoked. 
034:         * <p>
035:         * If you would instead like commands run in their own threads, you can
036:         * use as arguments Runnable commands that start their own threads
037:         * (or perhaps wrap within ThreadedExecutors). 
038:         * <p>
039:         * You can also use multiple
040:         * daemon objects, each using a different background thread. However,
041:         * one of the reasons for using a time daemon is to pool together
042:         * processing of infrequent tasks using a single background thread.
043:         * <p>
044:         * Background threads are created using a ThreadFactory. The
045:         * default factory does <em>not</em>
046:         * automatically <code>setDaemon</code> status.
047:         * <p>
048:         * The class uses Java timed waits for scheduling. These can vary
049:         * in precision across platforms, and provide no real-time guarantees
050:         * about meeting deadlines.
051:         * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
052:         **/
053:
054:        public class ClockDaemon extends ThreadFactoryUser {
055:
056:            /** tasks are maintained in a standard priority queue **/
057:            protected final Heap heap_ = new Heap(DefaultChannelCapacity.get());
058:
059:            protected static class TaskNode implements  Comparable {
060:                final Runnable command; // The command to run
061:                final long period; // The cycle period, or -1 if not periodic
062:                private long timeToRun_; // The time to run command
063:
064:                // Cancellation does not immediately remove node, it just
065:                // sets up lazy deletion bit, so is thrown away when next 
066:                // encountered in run loop
067:
068:                private boolean cancelled_ = false;
069:
070:                // Access to cancellation status and and run time needs sync 
071:                // since they can be written and read in different threads
072:
073:                synchronized void setCancelled() {
074:                    cancelled_ = true;
075:                }
076:
077:                synchronized boolean getCancelled() {
078:                    return cancelled_;
079:                }
080:
081:                synchronized void setTimeToRun(long w) {
082:                    timeToRun_ = w;
083:                }
084:
085:                synchronized long getTimeToRun() {
086:                    return timeToRun_;
087:                }
088:
089:                public int compareTo(Object other) {
090:                    long a = getTimeToRun();
091:                    long b = ((TaskNode) (other)).getTimeToRun();
092:                    return (a < b) ? -1 : ((a == b) ? 0 : 1);
093:                }
094:
095:                TaskNode(long w, Runnable c, long p) {
096:                    timeToRun_ = w;
097:                    command = c;
098:                    period = p;
099:                }
100:
101:                TaskNode(long w, Runnable c) {
102:                    this (w, c, -1);
103:                }
104:            }
105:
106:            /** 
107:             * Execute the given command at the given time.
108:             * @param date -- the absolute time to run the command, expressed
109:             * as a java.util.Date.
110:             * @param command -- the command to run at the given time.
111:             * @return taskID -- an opaque reference that can be used to cancel execution request
112:             **/
113:            public Object executeAt(Date date, Runnable command) {
114:                TaskNode task = new TaskNode(date.getTime(), command);
115:                heap_.insert(task);
116:                restart();
117:                return task;
118:            }
119:
120:            /** 
121:             * Excecute the given command after waiting for the given delay.
122:             * <p>
123:             * <b>Sample Usage.</b>
124:             * You can use a ClockDaemon to arrange timeout callbacks to break out
125:             * of stuck IO. For example (code sketch):
126:             * <pre>
127:             * class X {   ...
128:             * 
129:             *   ClockDaemon timer = ...
130:             *   Thread readerThread;
131:             *   FileInputStream datafile;
132:             * 
133:             *   void startReadThread() {
134:             *     datafile = new FileInputStream("data", ...);
135:             * 
136:             *     readerThread = new Thread(new Runnable() {
137:             *      public void run() {
138:             *        for(;;) {
139:             *          // try to gracefully exit before blocking
140:             *         if (Thread.currentThread().isInterrupted()) {
141:             *           quietlyWrapUpAndReturn();
142:             *         }
143:             *         else {
144:             *           try {
145:             *             int c = datafile.read();
146:             *             if (c == -1) break;
147:             *             else process(c);
148:             *           }
149:             *           catch (IOException ex) {
150:             *            cleanup();
151:             *            return;
152:             *          }
153:             *       }
154:             *     } };
155:             *
156:             *    readerThread.start();
157:             *
158:             *    // establish callback to cancel after 60 seconds
159:             *    timer.executeAfterDelay(60000, new Runnable() {
160:             *      readerThread.interrupt();    // try to interrupt thread
161:             *      datafile.close(); // force thread to lose its input file 
162:             *    });
163:             *   } 
164:             * }
165:             * </pre>
166:             * @param millisecondsToDelay -- the number of milliseconds
167:             * from now to run the command.
168:             * @param command -- the command to run after the delay.
169:             * @return taskID -- an opaque reference that can be used to cancel execution request
170:             **/
171:            public Object executeAfterDelay(long millisecondsToDelay,
172:                    Runnable command) {
173:                long runtime = System.currentTimeMillis() + millisecondsToDelay;
174:                TaskNode task = new TaskNode(runtime, command);
175:                heap_.insert(task);
176:                restart();
177:                return task;
178:            }
179:
180:            /** 
181:             * Execute the given command every <code>period</code> milliseconds.
182:             * If <code>startNow</code> is true, execution begins immediately,
183:             * otherwise, it begins after the first <code>period</code> delay.
184:             * <p>
185:             * <b>Sample Usage</b>. Here is one way
186:             * to update Swing components acting as progress indicators for
187:             * long-running actions.
188:             * <pre>
189:             * class X {
190:             *   JLabel statusLabel = ...;
191:             *
192:             *   int percentComplete = 0;
193:             *   synchronized int  getPercentComplete() { return percentComplete; }
194:             *   synchronized void setPercentComplete(int p) { percentComplete = p; }
195:             *
196:             *   ClockDaemon cd = ...;
197:             * 
198:             *   void startWorking() {
199:             *     Runnable showPct = new Runnable() {
200:             *       public void run() {
201:             *          SwingUtilities.invokeLater(new Runnable() {
202:             *            public void run() {
203:             *              statusLabel.setText(getPercentComplete() + "%");
204:             *            } 
205:             *          } 
206:             *       } 
207:             *     };
208:             *
209:             *     final Object updater = cd.executePeriodically(500, showPct, true);
210:             *
211:             *     Runnable action = new Runnable() {
212:             *       public void run() {
213:             *         for (int i = 0; i < 100; ++i) {
214:             *           work();
215:             *           setPercentComplete(i);
216:             *         }
217:             *         cd.cancel(updater);
218:             *       }
219:             *     };
220:             *
221:             *     new Thread(action).start();
222:             *   }
223:             * }  
224:             * </pre>
225:             * @param period -- the period, in milliseconds. Periods are
226:             *  measured from start-of-task to the next start-of-task. It is
227:             * generally a bad idea to use a period that is shorter than 
228:             * the expected task duration.
229:             * @param command -- the command to run at each cycle
230:             * @param startNow -- true if the cycle should start with execution
231:             * of the task now. Otherwise, the cycle starts with a delay of
232:             * <code>period</code> milliseconds.
233:             * @exception IllegalArgumentException if period less than or equal to zero.
234:             * @return taskID -- an opaque reference that can be used to cancel execution request
235:             **/
236:            public Object executePeriodically(long period, Runnable command,
237:                    boolean startNow) {
238:
239:                if (period <= 0)
240:                    throw new IllegalArgumentException();
241:
242:                long firstTime = System.currentTimeMillis();
243:                if (!startNow)
244:                    firstTime += period;
245:
246:                TaskNode task = new TaskNode(firstTime, command, period);
247:                heap_.insert(task);
248:                restart();
249:                return task;
250:            }
251:
252:            /** 
253:             * Cancel a scheduled task that has not yet been run. 
254:             * The task will be cancelled
255:             * upon the <em>next</em> opportunity to run it. This has no effect if
256:             * this is a one-shot task that has already executed.
257:             * Also, if an execution is in progress, it will complete normally.
258:             * (It may however be interrupted via getThread().interrupt()).
259:             * But if it is a periodic task, future iterations are cancelled. 
260:             * @param taskID -- a task reference returned by one of
261:             * the execute commands
262:             * @exception ClassCastException if the taskID argument is not 
263:             * of the type returned by an execute command.
264:             **/
265:            public static void cancel(Object taskID) {
266:                ((TaskNode) taskID).setCancelled();
267:            }
268:
269:            /** The thread used to process commands **/
270:            protected Thread thread_;
271:
272:            /**
273:             * Return the thread being used to process commands, or
274:             * null if there is no such thread. You can use this
275:             * to invoke any special methods on the thread, for
276:             * example, to interrupt it.
277:             **/
278:            public synchronized Thread getThread() {
279:                return thread_;
280:            }
281:
282:            /** set thread_ to null to indicate termination **/
283:            protected synchronized void clearThread() {
284:                thread_ = null;
285:            }
286:
287:            /**
288:             * Start (or restart) a thread to process commands, or wake
289:             * up an existing thread if one is already running. This
290:             * method can be invoked if the background thread crashed
291:             * due to an unrecoverable exception in an executed command.
292:             **/
293:
294:            public synchronized void restart() {
295:                if (thread_ == null) {
296:                    thread_ = threadFactory_.newThread(runLoop_);
297:                    thread_.start();
298:                } else
299:                    notify();
300:            }
301:
302:            /**
303:             * Cancel all tasks and interrupt the background thread executing
304:             * the current task, if any.
305:             * A new background thread will be started if new execution
306:             * requests are encountered. If the currently executing task
307:             * does not repsond to interrupts, the current thread may persist, even
308:             * if a new thread is started via restart().
309:             **/
310:            public synchronized void shutDown() {
311:                heap_.clear();
312:                if (thread_ != null)
313:                    thread_.interrupt();
314:                thread_ = null;
315:            }
316:
317:            /** Return the next task to execute, or null if thread is interrupted **/
318:            protected synchronized TaskNode nextTask() {
319:
320:                // Note: This code assumes that there is only one run loop thread
321:
322:                try {
323:                    while (!Thread.interrupted()) {
324:
325:                        // Using peek simplifies dealing with spurious wakeups
326:
327:                        TaskNode task = (TaskNode) (heap_.peek());
328:
329:                        if (task == null) {
330:                            wait();
331:                        } else {
332:                            long now = System.currentTimeMillis();
333:                            long when = task.getTimeToRun();
334:
335:                            if (when > now) { // false alarm wakeup
336:                                wait(when - now);
337:                            } else {
338:                                task = (TaskNode) (heap_.extract());
339:
340:                                if (!task.getCancelled()) { // Skip if cancelled by
341:
342:                                    if (task.period > 0) { // If periodic, requeue 
343:                                        task.setTimeToRun(now + task.period);
344:                                        heap_.insert(task);
345:                                    }
346:
347:                                    return task;
348:                                }
349:                            }
350:                        }
351:                    }
352:                } catch (InterruptedException ex) {
353:                } // fall through
354:
355:                return null; // on interrupt
356:            }
357:
358:            /**
359:             * The runloop is isolated in its own Runnable class
360:             * just so that the main 
361:             * class need not implement Runnable,  which would
362:             * allow others to directly invoke run, which is not supported.
363:             **/
364:
365:            protected class RunLoop implements  Runnable {
366:                public void run() {
367:                    try {
368:                        for (;;) {
369:                            TaskNode task = nextTask();
370:                            if (task != null)
371:                                task.command.run();
372:                            else
373:                                break;
374:                        }
375:                    } finally {
376:                        clearThread();
377:                    }
378:                }
379:            }
380:
381:            protected final RunLoop runLoop_;
382:
383:            /** 
384:             * Create a new ClockDaemon 
385:             **/
386:
387:            public ClockDaemon() {
388:                runLoop_ = new RunLoop();
389:            }
390:
391:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.