📄 hsqltimer.java
字号:
/* Copyright (c) 2001-2005, The HSQL Development Group * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 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. * * Neither the name of the HSQL Development Group nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS 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 HSQL DEVELOPMENT GROUP, HSQLDB.ORG, * OR CONTRIBUTORS 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. */package org.hsqldb.lib;import java.util.Date;/** * Provides facility for threads to schedule tasks for future execution in a * background thread. Tasks may be scheduled for one-time execution, or for * repeated execution at regular intervals. This class is a JDK 1.1 compatible * implementation required by HSQLDB because the java.util.Timer class is * available only in JDK 1.3+. * * @author boucherb@users * @version 1.7.2 * @since 1.7.2 */public class HsqlTimer implements ObjectComparator { /** The priority queue for the scheduled tasks. */ protected final TaskQueue taskQueue = new TaskQueue(16, (ObjectComparator) this); /** The inner runnable that executes tasks in the background thread. */ protected final TaskRunner taskRunner = new TaskRunner(); /** The background thread. */ protected Thread taskRunnerThread; /** The factory that procduces the background threads. */ protected ThreadFactory threadFactory; /** * Constructs a new HsqlTimer using the default thread factory * implementation. */ public HsqlTimer() { this(null); } /** * Constructs a new HsqlTimer using the specified thread factory * implementation. * * @param tf the ThreadFactory used to produce the background threads. * If null, the implementation supplied by HsqlThreadFactory will * be used. */ public HsqlTimer(ThreadFactory tf) { threadFactory = new HsqlThreadFactory(tf); } /** * ObjectComparator implemtation required to back priority queue * for scheduled tasks. * * @param a the first Task * @param b the second Task * @return 0 if equal, < 0 if a < b, > 0 if a > b */ public int compare(Object a, Object b) { long awhen; long bwhen; awhen = ((Task) (a)).getNextScheduled(); bwhen = ((Task) (b)).getNextScheduled(); // must return an int, so (awhen - bwhen) // might not be that great... (:-( // under realistic use (scheduled times in this era ;-), // awhen - bwhen is fine // return (awhen < bwhen) ? -1 : awhen == bwhen ? 0: 1; return (int) (awhen - bwhen); } /** * Retrieves the background thread that is currently being used to * execute submitted tasks. null is returned if there is no such thread. * * @return the current background thread or null */ public synchronized Thread getThread() { return taskRunnerThread; } /** * (Re)starts background processing of the task queue. */ public synchronized void restart() { if (taskRunnerThread == null) { taskRunnerThread = threadFactory.newThread(taskRunner); taskRunnerThread.setName("HSQLDB Timer @" + Integer.toHexString(this.hashCode())); taskRunnerThread.setDaemon(true); taskRunnerThread.start(); } else { notify(); } } /** * Causes the specified Runnable to be executed once in the background * after the specified delay. * * @param delay in milliseconds * @param r the Runnable to execute. * @return opaque reference to the internal task */ public Object scheduleAfter(long delay, Runnable r) { return addTask(now() + delay, r, 0, false); } /** * Causes the specified Runnable to be executed once in the background * at the specified time. * * @param date time at which to execute the specified Runnable * @param r the Runnable to execute. * @return opaque reference to the internal task */ public Object scheduleAt(Date date, Runnable r) { return addTask(date.getTime(), r, -1, false); } /** * Causes the specified Runnable to be executed periodically in the * background, starting at the specified time. * * @return opaque reference to the internal task * @param p the cycle period * @param relative if true, fixed rate sheduling else fixed period scheduling * @param date time at which to execute the specified Runnable * @param r the Runnable to execute */ public Object schedulePeriodicallyAt(Date date, long p, Runnable r, boolean relative) { if (p <= 0) { throw new IllegalArgumentException(); } return addTask(date.getTime(), r, p, relative); } /** * Causes the specified Runnable to be executed periodically in the * background, starting after the specified delay. * * @return opaque reference to the internal task * @param p the cycle period * @param relative if true, fixed rate sheduling else fixed period scheduling * @param delay in milliseconds * @param r the Runnable to execute. */ public Object schedulePeriodicallyAfter(long delay, long p, Runnable r, boolean relative) { if (p <= 0) { throw new IllegalArgumentException(); } return addTask(now() + delay, r, p, relative); } /** * Causes all pending tasks to be cancelled and then stops background * processing. */ public synchronized void shutDown() { taskQueue.clear(); if (taskRunnerThread != null) { taskRunnerThread.interrupt(); } taskRunnerThread = null; } /** * Causes the task referenced by the supplied argument to be cancelled. * If the referenced task is currently executing, it will continue until * finished but will not be rescheduled. * * @param task a task reference * @exception ClassCastException if the task argument cannot be cast * to the type of reference returned by a scheduleXXX method * invocation. */ public static void cancel(Object task) throws ClassCastException { if (task != null) { ((Task) task).cancel();// Trace.printSystemOut("HsqlTimer now() calls: " + nowCount); } } /** * Retrieves whether the specified argument references a cancelled task. * * @param task a task reference * @return true if referenced task is cancelled * @exception ClassCastException if the task argument cannot be cast * to the type of reference returned by a scheduleXXX method * invocation. */ public static boolean isCancelled(Object task) throws ClassCastException { return task == null ? true : ((Task) task).isCancelled(); } /** * Retrieves whether the specified argument references a task scheduled * periodically using fixed rate scheduling. * * @param task a task reference * @return true if the task is scheduled at a fixed rate * @exception ClassCastException if the task argument cannot be cast * to the type of reference returned by a scheduleXXX method * invocation. */ public static boolean isFixedRate(Object task) throws ClassCastException { return task == null ? false : ((Task) task).relative && ((Task) task).period > 0; } /** * Retrieves whether the specified argument references a task scheduled * periodically using fixed delay scheduling. * * @param task a task reference * @return if the task is scheduled using a fixed rate * @exception ClassCastException if the task argument cannot be cast * to the type of reference returned by a scheduleXXX method * invocation. */ public static boolean isFixedDelay(Object task) throws ClassCastException { return task == null ? false : !((Task) task).relative && ((Task) task).period > 0; } /** * Retrieves whether the specified argument references a task scheduled * for periodic execution. * * @param task a task reference * @return true ifthe task is scheduled for periodic execution * @exception ClassCastException if the task argument cannot be cast * to the type of reference returned by a scheduleXXX method * invocation. */ public static boolean isPeriodic(Object task) throws ClassCastException { return task == null ? false : ((Task) task).period != 0; } /** * Retrieves the last time the referenced task was executed, as a * Date object. If the task has never been executed, null is returned. * * @param task a task reference * @return the last time the referenced task was executed * @exception ClassCastException if the task argument cannot be cast * to the type of reference returned by a scheduleXXX method * invocation. */ public static Date getLastScheduled(Object task) throws ClassCastException { long last; last = task == null ? 0 : ((Task) task).getLastScheduled(); return last == 0 ? null : new Date(last); } /** * Resets the period for a task. * * @param task a task reference * @param period new period * @exception ClassCastException if the task argument cannot be cast * to the type of reference returned by a scheduleXXX method * invocation. */ public static void setPeriod(Object task, long period) throws ClassCastException { if (task == null) { return; } ((Task) task).setPeriod(period); } /** * Retrieves the next time the referenced task is due to be executed, as a * Date object. If the task has been cancelled, null is returned. * * @param task a task reference * @return the next time the referenced task is due to be executed * @exception ClassCastException if the task argument cannot be cast * to the type of reference returned by a scheduleXXX method * invocation. */ public static Date getNextScheduled(Object task) throws ClassCastException { return isCancelled(task) ? null : new Date(((Task) task).getNextScheduled()); } /** * Adds to the task queue a new Task object encapsulating the supplied * Runnable and scheduling arguments. * * @param n the time of the first execution * @param r the Runnable to execute * @param p the periodicity * @param b if true, use fixed rate else use fixed period * @return a reference to the scheduled task */ protected Task addTask(long n, Runnable r, long p, boolean b) { Task task; task = new Task(n, r, p, b); // sychronized taskQueue.add(task); // sychronized restart(); return task; } /** Sets the background thread to null. */ protected synchronized void clearThread() { taskRunnerThread = null; } /** * Retrieves the next task to execute, or null if the background thread
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -