Source Code Cross Referenced for Timer.java in  » Apache-Harmony-Java-SE » java-package » java » util » 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 » Apache Harmony Java SE » java package » java.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         */
017:
018:        package java.util;
019:
020:        import org.apache.harmony.luni.util.Msg;
021:
022:        /**
023:         * Timers are used to schedule jobs for execution in a background process. A
024:         * single thread is used for the scheduling and this thread has the option of
025:         * being a daemon thread. By calling <code>cancel</code> you can terminate a
026:         * timer and it's associated thread. All tasks which are scheduled to run after
027:         * this point are cancelled. Tasks are executed sequentially but are subject to
028:         * the delays from other tasks run methods. If a specific task takes an
029:         * excessive amount of time to run it may impact the time at which subsequent
030:         * tasks may run.
031:         * <p>
032:         * 
033:         * The Timer task does not offer any guarantees about the real-time nature of
034:         * scheduling tasks as it's underlying implementation relies on the
035:         * <code>Object.wait(long)</code> method.
036:         * <p>
037:         * 
038:         * Multiple threads can share a single Timer without the need for their own
039:         * synchronization.
040:         * 
041:         * @see TimerTask
042:         * @see java.lang.Object#wait(long)
043:         */
044:        public class Timer {
045:
046:            private static final class TimerImpl extends Thread {
047:
048:                private static final class TimerNode {
049:                    TimerNode parent, left, right;
050:
051:                    TimerTask task;
052:
053:                    public TimerNode(TimerTask value) {
054:                        this .task = value;
055:                    }
056:
057:                    public void deleteIfCancelled(TimerTree tasks) {
058:                        /*
059:                         * All changes in the tree structure during deleting this node
060:                         * affect only the structure of the subtree having this node as
061:                         * its root
062:                         */
063:                        if (left != null) {
064:                            left.deleteIfCancelled(tasks);
065:                        }
066:                        if (right != null) {
067:                            right.deleteIfCancelled(tasks);
068:                        }
069:                        if (task.cancelled) {
070:                            tasks.delete(this );
071:                            tasks.deletedCancelledNumber++;
072:                        }
073:                    }
074:                }
075:
076:                private static final class TimerTree {
077:
078:                    int deletedCancelledNumber;
079:
080:                    TimerNode root;
081:
082:                    boolean isEmpty() {
083:                        return root == null;
084:                    }
085:
086:                    void insert(TimerNode z) {
087:                        TimerNode y = null, x = root;
088:                        while (x != null) {
089:                            y = x;
090:                            if (z.task.getWhen() < x.task.getWhen()) {
091:                                x = x.left;
092:                            } else {
093:                                x = x.right;
094:                            }
095:                        }
096:                        z.parent = y;
097:                        if (y == null) {
098:                            root = z;
099:                        } else if (z.task.getWhen() < y.task.getWhen()) {
100:                            y.left = z;
101:                        } else {
102:                            y.right = z;
103:                        }
104:                    }
105:
106:                    void delete(TimerNode z) {
107:                        TimerNode y = null, x = null;
108:                        if (z.left == null || z.right == null) {
109:                            y = z;
110:                        } else {
111:                            y = successor(z);
112:                        }
113:                        if (y.left != null) {
114:                            x = y.left;
115:                        } else {
116:                            x = y.right;
117:                        }
118:                        if (x != null) {
119:                            x.parent = y.parent;
120:                        }
121:                        if (y.parent == null) {
122:                            root = x;
123:                        } else if (y == y.parent.left) {
124:                            y.parent.left = x;
125:                        } else {
126:                            y.parent.right = x;
127:                        }
128:                        if (y != z) {
129:                            z.task = y.task;
130:                        }
131:                    }
132:
133:                    private TimerNode successor(TimerNode x) {
134:                        if (x.right != null) {
135:                            return minimum(x.right);
136:                        }
137:                        TimerNode y = x.parent;
138:                        while (y != null && x == y.right) {
139:                            x = y;
140:                            y = y.parent;
141:                        }
142:                        return y;
143:                    }
144:
145:                    private TimerNode minimum(TimerNode x) {
146:                        while (x.left != null) {
147:                            x = x.left;
148:                        }
149:                        return x;
150:                    }
151:
152:                    TimerNode minimum() {
153:                        return minimum(root);
154:                    }
155:                }
156:
157:                /**
158:                 * True if the method cancel() of the Timer was called or the !!!stop()
159:                 * method was invoked
160:                 */
161:                private boolean cancelled;
162:
163:                /**
164:                 * True if the Timer has become garbage
165:                 */
166:                private boolean finished;
167:
168:                /**
169:                 * Vector consists of scheduled events, sorted according to
170:                 * <code>when</code> field of TaskScheduled object.
171:                 */
172:                private TimerTree tasks = new TimerTree();
173:
174:                /**
175:                 * Starts a new timer.
176:                 * 
177:                 * @param isDaemon
178:                 */
179:                TimerImpl(boolean isDaemon) {
180:                    this .setDaemon(isDaemon);
181:                    this .start();
182:                }
183:
184:                TimerImpl(String name, boolean isDaemon) {
185:                    this .setName(name);
186:                    this .setDaemon(isDaemon);
187:                    this .start();
188:                }
189:
190:                /**
191:                 * This method will be launched on separate thread for each Timer
192:                 * object.
193:                 */
194:                @Override
195:                public void run() {
196:                    while (true) {
197:                        TimerTask task;
198:                        synchronized (this ) {
199:                            // need to check cancelled inside the synchronized block
200:                            if (cancelled) {
201:                                return;
202:                            }
203:                            if (tasks.isEmpty()) {
204:                                if (finished) {
205:                                    return;
206:                                }
207:                                // no tasks scheduled -- sleep until any task appear
208:                                try {
209:                                    this .wait();
210:                                } catch (InterruptedException e) {
211:                                }
212:                                continue;
213:                            }
214:
215:                            long currentTime = System.currentTimeMillis();
216:
217:                            TimerNode taskNode = tasks.minimum();
218:                            task = taskNode.task;
219:                            long timeToSleep;
220:
221:                            synchronized (task.lock) {
222:                                if (task.cancelled) {
223:                                    tasks.delete(taskNode);
224:                                    continue;
225:                                }
226:
227:                                // check the time to sleep for the first task scheduled
228:                                timeToSleep = task.when - currentTime;
229:                            }
230:
231:                            if (timeToSleep > 0) {
232:                                // sleep!
233:                                try {
234:                                    this .wait(timeToSleep);
235:                                } catch (InterruptedException e) {
236:                                    // Ignored
237:                                }
238:                                continue;
239:                            }
240:
241:                            // no sleep is necessary before launching the task
242:
243:                            synchronized (task.lock) {
244:                                if (task.cancelled) {
245:                                    tasks.delete(taskNode);
246:                                    continue;
247:                                }
248:
249:                                // set time to schedule
250:                                task.setScheduledTime(task.when);
251:
252:                                // remove task from queue
253:                                tasks.delete(taskNode);
254:
255:                                // set when the next task should be launched
256:                                if (task.period >= 0) {
257:                                    // this is a repeating task,
258:                                    if (task.fixedRate) {
259:                                        // task is scheduled at fixed rate
260:                                        task.when = task.when + task.period;
261:                                    } else {
262:                                        // task is scheduled at fixed delay
263:                                        task.when = System.currentTimeMillis()
264:                                                + task.period;
265:                                    }
266:
267:                                    // insert this task into queue
268:                                    insertTask(task);
269:                                } else {
270:                                    task.when = 0;
271:                                }
272:                            }
273:                        }
274:
275:                        // run the task
276:                        try {
277:                            task.run();
278:                        } catch (Exception e) {
279:                            // Ignored
280:                        }
281:                    }
282:                }
283:
284:                private void insertTask(TimerTask newTask) {
285:                    // callers are synchronized
286:                    tasks.insert(new TimerNode(newTask));
287:                    this .notify();
288:                }
289:
290:                /**
291:                 * Cancels timer.
292:                 */
293:                public synchronized void cancel() {
294:                    cancelled = true;
295:                    tasks = new TimerTree();
296:                    this .notify();
297:                }
298:
299:                public int purge() {
300:                    if (tasks.isEmpty()) {
301:                        return 0;
302:                    }
303:                    // callers are synchronized
304:                    tasks.deletedCancelledNumber = 0;
305:                    tasks.root.deleteIfCancelled(tasks);
306:                    return tasks.deletedCancelledNumber;
307:                }
308:
309:            }
310:
311:            /* This object will be used in synchronization purposes */
312:            private TimerImpl impl;
313:
314:            // Used to finalize thread
315:            @SuppressWarnings("unused")
316:            private Object finalizer = new Object() { // $NON-LOCK-1$
317:                @Override
318:                protected void finalize() {
319:                    synchronized (impl) {
320:                        impl.finished = true;
321:                        impl.notify();
322:                    }
323:                }
324:            };
325:
326:            /**
327:             * Creates a new Timer which may be specified to be run as a Daemon Thread.
328:             * 
329:             * @param isDaemon
330:             *            true if Timers thread should be a daemon thread.
331:             */
332:            public Timer(boolean isDaemon) {
333:                impl = new TimerImpl(isDaemon);
334:            }
335:
336:            /**
337:             * Creates a new non-daemon Timer.
338:             */
339:            public Timer() {
340:                impl = new TimerImpl(false);
341:            }
342:
343:            public Timer(String name, boolean isDaemon) {
344:                impl = new TimerImpl(name, isDaemon);
345:            }
346:
347:            public Timer(String name) {
348:                impl = new TimerImpl(name, false);
349:            }
350:
351:            /**
352:             * Cancels the Timer and removed any scheduled tasks. If there is a
353:             * currently running task it is not effected. No more tasks may be scheduled
354:             * on this Timer. Subsequent calls do nothing.
355:             */
356:            public void cancel() {
357:                impl.cancel();
358:            }
359:
360:            public int purge() {
361:                synchronized (impl) {
362:                    return impl.purge();
363:                }
364:            }
365:
366:            /**
367:             * Schedule a task for single execution. If when is less than the current
368:             * time, it will be scheduled to executed as soon as possible.
369:             * 
370:             * @param task
371:             *            The task to schedule
372:             * @param when
373:             *            Time of execution
374:             * 
375:             * @exception IllegalArgumentException
376:             *                if when.getTime() < 0
377:             * @exception IllegalStateException
378:             *                if the timer has been cancelled, the task has been
379:             *                scheduled or cancelled.
380:             */
381:            public void schedule(TimerTask task, Date when) {
382:                if (when.getTime() < 0) {
383:                    throw new IllegalArgumentException();
384:                }
385:                long delay = when.getTime() - System.currentTimeMillis();
386:                scheduleImpl(task, delay < 0 ? 0 : delay, -1, false);
387:            }
388:
389:            /**
390:             * Schedule a task for single execution after a specific delay.
391:             * 
392:             * @param task
393:             *            The task to schedule
394:             * @param delay
395:             *            Amount of time before execution
396:             * 
397:             * @exception IllegalArgumentException
398:             *                if delay < 0
399:             * @exception IllegalStateException
400:             *                if the timer has been cancelled, the task has been
401:             *                scheduled or cancelled.
402:             */
403:            public void schedule(TimerTask task, long delay) {
404:                if (delay < 0) {
405:                    throw new IllegalArgumentException();
406:                }
407:                scheduleImpl(task, delay, -1, false);
408:            }
409:
410:            /**
411:             * Schedule a task for repeated fix-delay execution after a specific delay.
412:             * 
413:             * @param task
414:             *            The task to schedule
415:             * @param delay
416:             *            Amount of time before first execution
417:             * @param period
418:             *            Amount of time between subsequent executions
419:             * 
420:             * @exception IllegalArgumentException
421:             *                if delay < 0 or period < 0
422:             * @exception IllegalStateException
423:             *                if the timer has been cancelled, the task has been
424:             *                scheduled or cancelled.
425:             */
426:            public void schedule(TimerTask task, long delay, long period) {
427:                if (delay < 0 || period <= 0) {
428:                    throw new IllegalArgumentException();
429:                }
430:                scheduleImpl(task, delay, period, false);
431:            }
432:
433:            /**
434:             * Schedule a task for repeated fix-delay execution after a specific time
435:             * has been reached.
436:             * 
437:             * @param task
438:             *            The task to schedule
439:             * @param when
440:             *            Time of first execution
441:             * @param period
442:             *            Amount of time between subsequent executions
443:             * 
444:             * @exception IllegalArgumentException
445:             *                if when.getTime() < 0 or period < 0
446:             * @exception IllegalStateException
447:             *                if the timer has been cancelled, the task has been
448:             *                scheduled or cancelled.
449:             */
450:            public void schedule(TimerTask task, Date when, long period) {
451:                if (period <= 0 || when.getTime() < 0) {
452:                    throw new IllegalArgumentException();
453:                }
454:                long delay = when.getTime() - System.currentTimeMillis();
455:                scheduleImpl(task, delay < 0 ? 0 : delay, period, false);
456:            }
457:
458:            /**
459:             * Schedule a task for repeated fixed-rate execution after a specific delay
460:             * has been happened. The difference of fixed-rate is that it may bunch up
461:             * subsequent task runs to try to get the task repeating at it's desired
462:             * time.
463:             * 
464:             * @param task
465:             *            The task to schedule
466:             * @param delay
467:             *            Amount of time before first execution
468:             * @param period
469:             *            Amount of time between subsequent executions
470:             * 
471:             * @exception IllegalArgumentException
472:             *                if delay < 0 or period < 0
473:             * @exception IllegalStateException
474:             *                if the timer has been cancelled, the task has been
475:             *                scheduled or cancelled.
476:             */
477:            public void scheduleAtFixedRate(TimerTask task, long delay,
478:                    long period) {
479:                if (delay < 0 || period <= 0) {
480:                    throw new IllegalArgumentException();
481:                }
482:                scheduleImpl(task, delay, period, true);
483:            }
484:
485:            /**
486:             * Schedule a task for repeated fixed-rate execution after a specific time
487:             * has been reached. The difference of fixed-rate is that it may bunch up
488:             * subsequent task runs to try to get the task repeating at it's desired
489:             * time.
490:             * 
491:             * @param task
492:             *            The task to schedule
493:             * @param when
494:             *            Time of first execution
495:             * @param period
496:             *            Amount of time between subsequent executions
497:             * 
498:             * @exception IllegalArgumentException
499:             *                if when.getTime() < 0 or period < 0
500:             * @exception IllegalStateException
501:             *                if the timer has been cancelled, the task has been
502:             *                scheduled or cancelled.
503:             */
504:            public void scheduleAtFixedRate(TimerTask task, Date when,
505:                    long period) {
506:                if (period <= 0 || when.getTime() < 0) {
507:                    throw new IllegalArgumentException();
508:                }
509:                long delay = when.getTime() - System.currentTimeMillis();
510:                scheduleImpl(task, delay < 0 ? 0 : delay, period, true);
511:            }
512:
513:            /**
514:             * Schedule a task.
515:             * 
516:             * @param task
517:             * @param delay
518:             * @param period
519:             * @param fixed
520:             */
521:            private void scheduleImpl(TimerTask task, long delay, long period,
522:                    boolean fixed) {
523:                synchronized (impl) {
524:                    if (impl.cancelled) {
525:                        throw new IllegalStateException(Msg.getString("K00f3")); //$NON-NLS-1$
526:                    }
527:
528:                    long when = delay + System.currentTimeMillis();
529:
530:                    if (when < 0) {
531:                        throw new IllegalArgumentException(Msg
532:                                .getString("K00f5")); //$NON-NLS-1$
533:                    }
534:
535:                    synchronized (task.lock) {
536:                        if (task.isScheduled()) {
537:                            throw new IllegalStateException(Msg
538:                                    .getString("K00f6")); //$NON-NLS-1$
539:                        }
540:
541:                        if (task.cancelled) {
542:                            throw new IllegalStateException(Msg
543:                                    .getString("K00f7")); //$NON-NLS-1$
544:                        }
545:
546:                        task.when = when;
547:                        task.period = period;
548:                        task.fixedRate = fixed;
549:                    }
550:
551:                    // insert the newTask into queue
552:                    impl.insertTask(task);
553:                }
554:            }
555:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.