⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hsqltimer.java

📁 纯Java的数据库
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
            return false;        }    }    /**     * Retrieves whether the specified argument references a task scheduled     * for periodic execution.     *     * @param task a task reference     * @return true if the task is scheduled for periodic execution     */    public static boolean isPeriodic(final Object task) {        return (task instanceof Task) ? (((Task) task).period > 0)                                      : false;    }    /**     * 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; null if never     */    public static Date getLastScheduled(Object task) {        if (task instanceof Task) {            final Task ltask = (Task) task;            final long last  = ltask.getLastScheduled();            return (last == 0) ? null                               : new Date(last);        } else {            return null;        }    }    /**     * Sets the periodicity of the designated task to a new value. <p>     *     * If the designated task is cancelled or the new period is identical to the     * task's current period, then this invocation has essentially no effect     * and the submitted object is returned. <p>     *     * Otherwise, if the new period is greater than the designated task's     * current period, then a simple assignment occurs and the submittted     * object is returned. <p>     *     * If neither case holds, then the designated task is cancelled and a new,     * equivalent task with the new period is scheduled for immediate first     * execution and returned to the caller. <p>     *     * @return a task reference, as per the rules stated above.     * @param task the task whose periodicity is to be set     * @param period the new period     */    public static Object setPeriod(final Object task, final long period) {        return (task instanceof Task) ? ((Task) task).setPeriod(period)                                      : task;    }    /**     * Retrieves the next time the referenced task is due to be executed, as a     * Date object. If the referenced task is cancelled, null is returned.     *     * @param task a task reference     * @return the next time the referenced task is due to be executed     */    public static Date getNextScheduled(Object task) {        if (task instanceof Task) {            final Task ltask = (Task) task;            final long next  = ltask.isCancelled() ? 0                                                   : ltask.getNextScheduled();            return next == 0 ? null                             : new Date(next);        } else {            return null;        }    }    /**     * Adds to the task queue a new Task object encapsulating the supplied     * Runnable and scheduling arguments.     *     * @param first the time of the task's first execution     * @param runnable the Runnable to execute     * @param period the task's periodicity     * @param relative if true, use fixed rate else use fixed delay scheduling     * @return an opaque reference to the internal task     */    protected Task addTask(final long first, final Runnable runnable,                           final long period, boolean relative) {        if (this.isShutdown) {            throw new IllegalStateException("shutdown");        }        final Task task = new Task(first, runnable, period, relative);        // sychronized        this.taskQueue.addTask(task);        // sychronized        this.restart();        return task;    }    /** Sets the background thread to null. */    protected synchronized void clearThread() {//#ifdef JAVA2FULL        try {            taskRunnerThread.setContextClassLoader(null);        } catch (Throwable t) {}//#endif JAVA2FULL        taskRunnerThread = null;    }    /**     * Retrieves the next task to execute, or null if this timer is shutdown,     * the current thread is interrupted, or there are no queued tasks.     *     * @return the next task to execute, or null     */    protected Task nextTask() {        try {            while (!this.isShutdown || Thread.interrupted()) {                long now;                long next;                long wait;                Task task;                // synchronized to ensure removeTask                // applies only to the peeked task,                // when the computed wait <= 0                synchronized (this.taskQueue) {                    task = this.taskQueue.peekTask();                    if (task == null) {                        // queue is empty                        break;                    }                    now  = System.currentTimeMillis();                    next = task.next;                    wait = (next - now);                    if (wait > 0) {                        // release ownership of taskQueue monitor and await                        // notification of task addition or cancellation,                        // at most until the time when the peeked task is                        // next supposed to execute                        this.taskQueue.park(wait);                        continue;           // to top of loop                    } else {                        this.taskQueue.removeTask();                    }                }                long period = task.period;                if (period > 0) {           // repeated task                    if (task.relative) {    // using fixed rate shceduling                        final long late = (now - next);                        if (late > period) {                            // ensure that really late tasks don't                            // completely saturate the head of the                            // task queue                            period = 0;     // TODO: is -1, -2 ... fairer?                        } else if (late > 0) {                            // compensate for scheduling overruns                            period -= late;                        }                    }                    task.updateSchedule(now, now + period);                    this.taskQueue.addTask(task);                }                return task;            }        } catch (InterruptedException e) {            //e.printStackTrace();        }        return null;    }    /**     * stats var     */    static int nowCount = 0;    /**     * Convenience method replacing the longer incantation:     * System.currentTimeMillis()     *     * @return System.currentTimeMillis()     */    private static long now() {        nowCount++;        return System.currentTimeMillis();    }    /**     * The Runnable that the background thread uses to execute     * scheduled tasks. <p>     *     * <b>Note:</b> Outer class could simply implement Runnable,     * but using an inner class protects the public run method     * from potential abuse.     */    protected class TaskRunner implements Runnable {        /**         * Runs the next available task in the background thread. <p>         *         * When there are no available tasks, the background         * thread dies and its instance field is cleared until         * tasks once again become available.         */        public void run() {            try {                do {                    final Task task = HsqlTimer.this.nextTask();                    if (task == null) {                        break;                    }                    // PROBLEM: If the runnable throws an exception other                    //          than InterruptedException (which likely stems                    //          naturally from calling shutdownImmediately()                    //          or getThread().interrupt()), this will still                    //          cause the loop to exit, which is to say that                    //          task scheduling will stop until a new task is                    //          added or the timer is restarted directly, even                    //          though there may still be uncancelled tasks                    //          left on the queue.                    //                    // TODO:    Clarify and establish a contract regarding                    //          the difference between InterruptedException,                    //          RuntimeException and other things, like                    //          UndeclaredThrowableException.                    //                    // SOL'N:   At present, we simply require each runnable to                    //          understand its part of the implicit contract,                    //          which is to deal with exceptions internally                    //          (not throw them up to the timer), with the                    //          possible exception of InterruptedException.                    //                    //          If the integrity of work performed by the                    //          runnable may be adversely affected by an                    //          unplanned interruption, the runnable should                    //          deal with this directly, for instance by                    //          catching the InterruptedException, ensuring                    //          that some integrity preserving state is                    //          attained, and then rethrowing the exception.                    task.runnable.run();                } while (true);            } finally {                HsqlTimer.this.clearThread();            }        }    }    /**     * Encapsulates a Runnable and its scheduling attributes.     *     * Essentially, a wrapper class used to schedule a Runnable object     * for execution by the enclosing HsqlTimer's TaskRunner in a     * background thread.     */    protected class Task {        /** What to run. */        Runnable runnable;        /** The periodic interval, or 0 if one-shot. */        long period;        /** The time this task was last executed, or 0 if never. */        long last;        /** The next time this task is scheduled to execute. */        long next;        /**         * Whether to silently remove this task instead of running it,         * the next time (if ever) it makes its way to the head of the         * timer queue.         */        boolean cancelled = false;        /** Serializes concurrent access to the cancelled field. */        private Object cancel_mutex = new Object();        /**         * Scheduling policy flag. <p>         *         * When true, scheduling is fixed rate (as opposed to fixed delay),         * and schedule updates are calculated relative to when the task was         * was last run rather than a fixed delay starting from the current         * wall-clock time provided by System.currentTimeMillis().  <p>         *         * This helps normalize scheduling for tasks that must attempt to         * maintain a fixed rate of execution.         */        final boolean relative;        /**         * Constructs a new Task object encapulating the specified Runnable         * and scheduling arguments.         *         * @param first the first time to execute         * @param runnable the Runnable to execute         * @param period the periodicity of execution         * @param relative if true, use fixed rate scheduling else fixed delay         */        Task(final long first, final Runnable runnable, final long period,                final boolean relative) {            this.next     = first;            this.runnable = runnable;            this.period   = period;            this.relative = relative;        }        // fixed reported race condition        /** Sets this task's cancelled flag true and signals its taskQueue. */        void cancel() {            boolean signalCancelled = false;            synchronized (cancel_mutex) {                if (!cancelled) {                    cancelled = signalCancelled = true;                }            }            if (signalCancelled) {                HsqlTimer.this.taskQueue.signalTaskCancelled(this);            }        }        /**         * Retrieves whether this task is cancelled.         *         * @return true if cancelled, else false         */        boolean isCancelled() {            synchronized (cancel_mutex) {                return cancelled;            }        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -