📄 hsqltimer.java
字号:
* is interrupted. * * @return the next task to execute, or null */ protected synchronized Task nextTask() { Task task; long now; long last; long next; long late; long period; boolean relative; try { while (!Thread.interrupted()) { task = (Task) (taskQueue.peek()); if (task == null) { wait(); } else { now = now(); next = task.getNextScheduled(); if (next > now) { wait(next - now); } else { task = (Task) taskQueue.remove(); if (task != null &&!task.isCancelled()) { period = task.period; if (period > 0) { now = now(); if (task.relative) { late = now - next; if (late > 0) { period -= late; } } next = now + period; task.setNextScheduled(next); taskQueue.add(task); } return task; } } } } } catch (InterruptedException e) { // e.printStackTrace() } // interrupted return null; } 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 { public void run() { Task task; try { do { task = HsqlTimer.this.nextTask(); if (task == null) { break; } task.setLastScheduled(now()); task.runnable.run(); } while (true); } finally { HsqlTimer.this.clearThread(); } } } /** * 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 */ final Runnable runnable; /** The periodic interval, or 0 if one-shot */ long period; /** The time this task was last executed, or 0 if never */ private long last; /** The next time this task is scheduled to execute */ private long next; /** * Whether to remove this task instead of running it * the next time it makes its way to the head of the * timer queue. */ private boolean cancelled = false; /** protect the cancelled field under concurrent access */ private Object cancel_mutex = new Object(); /** * Whether periodic task is sheduled using fixed delay or fixed rate. * * When true, scheduling is fixed rate as opposed to fixed delay * and nextScheduled is 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(). This helps tasks that must attempt * to maintain a fixed rate of execution under Java's approximate * wait() and Thread.sleep(millis). */ final boolean relative; /** * Constructs a new Task object encapulating the specified Runnable * and scheduling arguments. * * @param n the next time to execute * @param r the Runnable to execute * @param p the periodicity of execution * @param b if true, use fixed rate scheduling else fixed period */ Task(long n, Runnable r, long p, boolean b) { last = 0; next = n; runnable = r; period = p; relative = b; } /** Sets this task's cancelled flag true. */ void cancel() { synchronized (cancel_mutex) { cancelled = true; } } /** * Retrieves whether this task is cancelled. * * @return true if cancelled, else false */ boolean isCancelled() { synchronized (cancel_mutex) { return cancelled; } } /** * Retrieves the instant in time just before this task was * last executed by the background thread. A value of zero * indicates that this task has never been executed. * * @return the last time this task was executed or zero if never */ synchronized long getLastScheduled() { return last; } /** * Sets the time at which this task reports it was last executed. * * @param l the new value for the last executed attribute */ synchronized void setLastScheduled(long l) { last = l; } /** * Retrieves the time at which this task is next scheduled for * execution. * * @return the time at which this task is next scheduled for * execution */ synchronized long getNextScheduled() { return next; } /** * Sets the new time at which this task is next scheduled for * execution. * * @param n the new time at which this task is next scheduled for * execution */ synchronized void setNextScheduled(long n) { next = n; } /** * Sets the period to wait. * * @param n the new period */ synchronized void setPeriod(long n) { period = n; } } /** * Extends HsqlArrayHeap to allow all pending tasks to be cancelled when * the queue is cleared. Currently, this is done for reporting purposes * only, as there is no public interface to reinsert Task objects after * they have been removed. */ protected class TaskQueue extends HsqlArrayHeap { /** * Constructs a new TaskQueue with the specified initial capacity and * ObjectComparator. * * @param capacity the initial capacity of the queue * @param oc The ObjectComparator this queue uses to maintain its * Heap invariant. */ TaskQueue(int capacity, ObjectComparator oc) { super(capacity, oc); } /** Cancels all pending tasks and removes them from this queue. */ public synchronized void clear() { for (int i = 0; i < count; i++) { ((Task) heap[i]).cancel(); heap[i] = null; } count = 0; } }// ---------------------------------- tests ------------------------------------// static class TestTask implements Runnable {// String name;// HsqlTimer timer;// Object tid;// int runs = 0;// long last;// long total = 0;// Thread sleeper;//// TestTask(String name) {// this.name = name;// try {// System.runFinalizersOnExit(true);// } catch (Exception e) {//// }// }//// public void run() {// System.out.println(this);// if (timer.getLastScheduled(tid) == null) {// System.out.println("no last sched.");// } else {// runs++;// if (runs == 1) {// last = now();// } else {// long now = now();// total += (now - last);// last = now;// System.out.println("runs: " + (runs -1));// System.out.println("totl: " + total);// System.out.flush();// }// }// System.out.println("------------------");// if (runs == 10) {// timer.shutDown();// sleeper.interrupt();// }// }//// public String toString() {// return name;// }//// protected void printstats() {// System.out.println(this + " avg. latency: " + (total/(runs-1)));// }// }//// public static void main(String[] args) {// HsqlTimer timer;// TestTask tt1;// TestTask tt2;// Thread sleeper;//// timer = new HsqlTimer();//// // need this to run tests now, since// // taskRunnerThread is now daemon.// // Otherwise, timer thread exits// // immediately when this thread exits.// sleeper = new Thread() {// public void run() {// try {// sleep(Long.MAX_VALUE);// } catch (Exception e) {// // do nothing// }// }// };//// sleeper.start();//// Runnable r = new Runnable() {// long x;// int runs = 0;// public void run() {// for (int i = 0; i < 1000000; i++) {// x = (long) ((x + 6) * (double)12) - 100;// }// }// };//// tt2 = new TestTask("Task 2");// tt2.timer = timer;// tt2.sleeper = sleeper;// tt2.tid = (Task) timer.schedulePeriodicallyAfter(0, 500, tt2, false);//// tt1 = new TestTask("Task 1");// tt1.timer = timer;// tt1.sleeper = sleeper;// tt1.tid = (Task) timer.schedulePeriodicallyAfter(0, 500, tt1, true);//// timer.schedulePeriodicallyAfter(0,1, r, false);//// try {// sleeper.join();// } catch (Exception e) {}//// tt1.printstats();// tt2.printstats();//// }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -