/**
 * This class represents a timer task queue: a priority queue of TimerTasks,
 * ordered on nextExecutionTime.  Each Timer object has one of these, which it
 * shares with its TimerThread.  Internally this class uses a heap, which
 * offers log(n) performance for the add, removeMin and rescheduleMin
 * operations, and constant time performance for the getMin operation.
 */
class TaskQueue {
    /**
     * Priority queue represented as a balanced binary heap: the two children
     * of queue[n] are queue[2*n] and queue[2*n+1].  The priority queue is
     * ordered on the nextExecutionTime field: The TimerTask with the lowest
     * nextExecutionTime is in queue[1] (assuming the queue is nonempty).  For
     * each node n in the heap, and each descendant of n, d,
     * n.nextExecutionTime <= d.nextExecutionTime. 
     */
    private TimerTask[] queue = new TimerTask[128];
......
}
呵呵,粗粗看了一下,没有明白。

解决方案 »

  1.   

    java.util.Timerclass TaskQueue
    Priority queue represented as a balanced binary heap通俗的讲就是一个数组表示,但是我要获得它的最小值:
    如果直接用数组:查找时间是 o(n);
    当然可以排序:查找时间就是 lg(n);但是新增和删除的时候就要移动不少数据,可以认为是o(n);用一个平衡二分堆实现达到:查找,新增和删除都是 lg(n);
      

  2.   

    class TaskQueue {
        /**
         * Priority queue represented as a balanced binary heap: the two children
         * of queue[n] are queue[2*n] and queue[2*n+1].  The priority queue is
         * ordered on the nextExecutionTime field: The TimerTask with the lowest
         * nextExecutionTime is in queue[1] (assuming the queue is nonempty).  For
         * each node n in the heap, and each descendant of n, d,
         * n.nextExecutionTime <= d.nextExecutionTime. 
         */
        private TimerTask[] queue = new TimerTask[128];    /**
         * The number of tasks in the priority queue.  (The tasks are stored in
         * queue[1] up to queue[size]).
         */
        private int size = 0;    /**
         * Adds a new task to the priority queue.
         */
        void add(TimerTask task) {
            // Grow backing store if necessary
            if (++size == queue.length) {
                TimerTask[] newQueue = new TimerTask[2*queue.length];
                System.arraycopy(queue, 0, newQueue, 0, size);
                queue = newQueue;
            }        queue[size] = task;
            fixUp(size);
        }    /**
         * Return the "head task" of the priority queue.  (The head task is an
         * task with the lowest nextExecutionTime.)
         */
        TimerTask getMin() {
            return queue[1];
        }    /**
         * Remove the head task from the priority queue.
         */
        void removeMin() {
            queue[1] = queue[size];
            queue[size--] = null;  // Drop extra reference to prevent memory leak
            fixDown(1);
        }    /**
         * Sets the nextExecutionTime associated with the head task to the 
         * specified value, and adjusts priority queue accordingly.
         */
        void rescheduleMin(long newTime) {
            queue[1].nextExecutionTime = newTime;
            fixDown(1);
        }    /**
         * Returns true if the priority queue contains no elements.
         */
        boolean isEmpty() {
            return size==0;
        }    /**
         * Removes all elements from the priority queue.
         */
        void clear() {
            // Null out task references to prevent memory leak
            for (int i=1; i<=size; i++)
                queue[i] = null;        size = 0;
        }    /**
         * Establishes the heap invariant (described above) assuming the heap
         * satisfies the invariant except possibly for the leaf-node indexed by k
         * (which may have a nextExecutionTime less than its parent's).
         *
         * This method functions by "promoting" queue[k] up the hierarchy
         * (by swapping it with its parent) repeatedly until queue[k]'s
         * nextExecutionTime is greater than or equal to that of its parent.
         */
        private void fixUp(int k) {
            while (k > 1) {
                int j = k >> 1;
                if (queue[j].nextExecutionTime <= queue[k].nextExecutionTime)
                    break;
                TimerTask tmp = queue[j];  queue[j] = queue[k]; queue[k] = tmp;
                k = j;
            }
        }    /**
         * Establishes the heap invariant (described above) in the subtree
         * rooted at k, which is assumed to satisfy the heap invariant except
         * possibly for node k itself (which may have a nextExecutionTime greater
         * than its children's).
         *
         * This method functions by "demoting" queue[k] down the hierarchy
         * (by swapping it with its smaller child) repeatedly until queue[k]'s
         * nextExecutionTime is less than or equal to those of its children.
         */
        private void fixDown(int k) {
            int j;
            while ((j = k << 1) <= size) {
                if (j < size &&
                    queue[j].nextExecutionTime > queue[j+1].nextExecutionTime)
                    j++; // j indexes smallest kid
                if (queue[k].nextExecutionTime <= queue[j].nextExecutionTime)
                    break;
                TimerTask tmp = queue[j];  queue[j] = queue[k]; queue[k] = tmp;
                k = j;
            }
        }
    }
      

  3.   

    void add(TimerTask task) {
    ...
    fixUp(size);
    }
    这里就是堆数据结构的关键,每次添加数据进这个数组就会有一个重排的过程,这个过程就是一个排序堆的应用当然不是排序,它就是用来获取最大值(或最小值)的时间复杂度的
    堆分最大值堆和最小值堆,区别在于heap[1]的值是这个数组中的最大值还是最小值