- 1 package java.util;
- 2 import java.util.Date;
- 3 import java.util.concurrent.atomic.AtomicInteger;
- 4 5 6 public class Timer {
- 7 8 private final TaskQueue queue = new TaskQueue();
- 9 10 11 private final TimerThread thread = new TimerThread(queue);
- 12 13 14 private final Object threadReaper = new Object() {
- 15 protected void finalize() throws Throwable {
- 16 synchronized(queue) {
- 17 thread.newTasksMayBeScheduled = false;
- 18 queue.notify(); // In case queue is empty.
- 19
- }
- 20
- }
- 21
- };
- 22 23 24 private final static AtomicInteger nextSerialNumber = new AtomicInteger(0);
- 25 private static int serialNumber() {
- 26
- return nextSerialNumber.getAndIncrement();
- 27
- }
- 28 29 30 public Timer() {
- 31 this("Timer-" + serialNumber());
- 32
- }
- 33 34 35 public Timer(boolean isDaemon) {
- 36 this("Timer-" + serialNumber(), isDaemon);
- 37
- }
- 38 39 40 public Timer(String name) {
- 41 thread.setName(name);
- 42 thread.start();
- 43
- }
- 44 45 //在初始化Timer时,确定线程名称,以及是否是守护线程 ,开启线程
- 46 public Timer(String name, boolean isDaemon) {
- 47 thread.setName(name);
- 48 thread.setDaemon(isDaemon);
- 49 thread.start();
- 50
- }
- 51 52 53 public void schedule(TimerTask task, long delay) {
- 54
- if (delay < 0) 55
- throw new IllegalArgumentException("Negative delay.");
- 56 sched(task, System.currentTimeMillis() + delay, 0);
- 57
- }
- 58 59 60 public void schedule(TimerTask task, Date time) {
- 61 sched(task, time.getTime(), 0);
- 62
- }
- 63 64 65 public void schedule(TimerTask task, long delay, long period) {
- 66
- if (delay < 0) 67
- throw new IllegalArgumentException("Negative delay.");
- 68
- if (period <= 0) 69
- throw new IllegalArgumentException("Non-positive period.");
- 70 sched(task, System.currentTimeMillis() + delay, -period);
- 71
- }
- 72 73 74 public void schedule(TimerTask task, Date firstTime, long period) {
- 75
- if (period <= 0) 76
- throw new IllegalArgumentException("Non-positive period.");
- 77 sched(task, firstTime.getTime(), -period);
- 78
- }
- 79 80 81 public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
- 82
- if (delay < 0) 83
- throw new IllegalArgumentException("Negative delay.");
- 84
- if (period <= 0) 85
- throw new IllegalArgumentException("Non-positive period.");
- 86 sched(task, System.currentTimeMillis() + delay, period);
- 87
- }
- 88 89 90 public void scheduleAtFixedRate(TimerTask task, Date firstTime, 91 long period) {
- 92
- if (period <= 0) 93
- throw new IllegalArgumentException("Non-positive period.");
- 94 sched(task, firstTime.getTime(), period);
- 95
- }
- 96 97 98 private void sched(TimerTask task, long time, long period) {
- 99
- if (time < 0) 100
- throw new IllegalArgumentException("Illegal execution time.");
- 101 102 // Constrain value of period sufficiently to prevent numeric
- 103 // overflow while still being effectively infinitely large.
- 104
- if (Math.abs(period) > (Long.MAX_VALUE >> 1)) 105 period >>= 1;
- 106 107 synchronized(queue) {
- 108
- if (!thread.newTasksMayBeScheduled) 109
- throw new IllegalStateException("Timer already cancelled.");
- 110 111 synchronized(task.lock) {
- 112
- if (task.state != TimerTask.VIRGIN) 113
- throw new IllegalStateException(114 "Task already scheduled or cancelled");
- 115 task.nextExecutionTime = time;
- 116 task.period = period;
- 117 task.state = TimerTask.SCHEDULED;
- 118
- }
- 119 120 queue.add(task);
- 121
- if (queue.getMin() == task) 122 queue.notify();
- 123
- }
- 124
- }
- 125 126 127 public void cancel() {
- 128 synchronized(queue) {
- 129 thread.newTasksMayBeScheduled = false;
- 130 queue.clear();
- 131 queue.notify(); // In case queue was already empty.
- 132
- }
- 133
- }
- 134 135 //净化,清除timer中标记为CANCELLED的TIMETASK, 返回值为清除个数
- 136 public int purge() {
- 137 int result = 0;
- 138 139 synchronized(queue) {
- 140
- for (int i = queue.size(); i > 0; i--) {
- 141
- if (queue.get(i).state == TimerTask.CANCELLED) {
- 142 queue.quickRemove(i);
- 143 result++;
- 144
- }
- 145
- }
- 146 147
- if (result != 0) 148 queue.heapify();
- 149
- }
- 150 151
- return result;
- 152
- }
- 153
- }
- 154 155 //自定义线程
- 156 class TimerThread extends Thread {
- 157 158 boolean newTasksMayBeScheduled = true;
- 159 160 161 private TaskQueue queue;
- 162 163 TimerThread(TaskQueue queue) {
- 164 this.queue = queue;
- 165
- }
- 166 167 public void run() {
- 168
- try {
- 169 mainLoop();
- 170
- } finally {
- 171 // Someone killed this Thread, behave as if Timer cancelled
- 172 synchronized(queue) {
- 173 newTasksMayBeScheduled = false;
- 174 queue.clear(); // Eliminate obsolete references
- 175
- }
- 176
- }
- 177
- }
- 178 179 180 private void mainLoop() {
- 181
- while (true) {
- 182
- try {
- 183 TimerTask task;
- 184 boolean taskFired;
- 185 synchronized(queue) {
- 186 // Wait for queue to become non-empty
- 187
- while (queue.isEmpty() && newTasksMayBeScheduled) 188 queue.wait();
- 189
- if (queue.isEmpty()) 190
- break; // Queue is empty and will forever remain; die
- 191 192 // Queue nonempty; look at first evt and do the right thing
- 193 long currentTime,
- executionTime;
- 194 task = queue.getMin();
- 195 synchronized(task.lock) {
- 196
- if (task.state == TimerTask.CANCELLED) { //移除 状态为已执行完毕的任务
- 197 queue.removeMin();
- 198
- continue;
- 199
- }
- 200 currentTime = System.currentTimeMillis();
- 201 executionTime = task.nextExecutionTime;
- 202
- if (taskFired = (executionTime <= currentTime)) {
- 203
- if (task.period == 0) { // 循环条件为0时,直接清除任务,并将任务状态置为非循环任务,并执行一次任务!
- 204 queue.removeMin();
- 205 task.state = TimerTask.EXECUTED;
- 206
- } else { //区分 两种循环类别的关键
- 207 queue.rescheduleMin(208 task.period < 0 ? currentTime - task.period 209 : executionTime + task.period);
- 210
- }
- 211
- }
- 212
- }
- 213
- if (!taskFired) // 当下次执行任务时间大于当前时间 等待
- 214 queue.wait(executionTime - currentTime);
- 215
- }
- 216
- if (taskFired) // 执行任务
- 217 task.run();
- 218
- } catch(InterruptedException e) {
- 219
- }
- 220
- }
- 221
- }
- 222
- }
- 223 224
- /**
- 225 *
- 226 * 任务管理内部类
- 227 */
- 228 class TaskQueue {
- 229 230 //初始化 128个空间,实际使用127个 位置编号为0的位置不使用
- 231 private TimerTask[] queue = new TimerTask[128];
- 232 233 234 private int size = 0;
- 235 236 237 int size() {
- 238
- return size;
- 239
- }
- 240 241 //添加任务,如果空间不足,空间*2,,然后排序(将nextExecutionTime最小的排到1位置)
- 242 void add(TimerTask task) {
- 243 // Grow backing store if necessary
- 244
- if (size + 1 == queue.length) 245 queue = Arrays.copyOf(queue, 2 * queue.length);
- 246 247 queue[++size] = task;
- 248 fixUp(size);
- 249
- }
- 250 251 //得到最小的nextExecutionTime的任务
- 252 TimerTask getMin() {
- 253
- return queue[1];
- 254
- }
- 255 256 //得到指定位置的任务
- 257 TimerTask get(int i) {
- 258
- return queue[i];
- 259
- }
- 260 261 //删除最小nextExecutionTime的任务,排序(将nextExecutionTime最小的排到1位置)
- 262 void removeMin() {
- 263 queue[1] = queue[size];
- 264 queue[size--] = null; // Drop extra reference to prevent memory leak
- 265 fixDown(1);
- 266
- }
- 267 268 //快速删除指定位置的任务
- 269 void quickRemove(int i) {
- 270 assert i <= size;
- 271 272 queue[i] = queue[size];
- 273 queue[size--] = null; // Drop extra ref to prevent memory leak
- 274
- }
- 275 276 //重新设置最小nextExecutionTime的任务的nextExecutionTime,排序(将nextExecutionTime最小的排到1位置)
- 277 void rescheduleMin(long newTime) {
- 278 queue[1].nextExecutionTime = newTime;
- 279 fixDown(1);
- 280
- }
- 281 282 //数组是否为空
- 283 boolean isEmpty() {
- 284
- return size == 0;
- 285
- }
- 286 287 //清空数组
- 288 void clear() {
- 289 // Null out task references to prevent memory leak
- 290
- for (int i = 1; i <= size; i++) 291 queue[i] = null;
- 292 293 size = 0;
- 294
- }
- 295 296 //将nextExecutionTime最小的排到1位置
- 297 private void fixUp(int k) {
- 298
- while (k > 1) {
- 299 int j = k >> 1;
- 300
- if (queue[j].nextExecutionTime <= queue[k].nextExecutionTime) 301
- break;
- 302 TimerTask tmp = queue[j];
- queue[j] = queue[k];
- queue[k] = tmp;
- 303 k = j;
- 304
- }
- 305
- }
- 306 307 //将nextExecutionTime最小的排到1位置
- 308 private void fixDown(int k) {
- 309 int j;
- 310
- while ((j = k << 1) <= size && j > 0) {
- 311
- if (j < size && 312 queue[j].nextExecutionTime > queue[j + 1].nextExecutionTime) 313 j++; // j indexes smallest kid
- 314
- if (queue[k].nextExecutionTime <= queue[j].nextExecutionTime) 315
- break;
- 316 TimerTask tmp = queue[j];
- queue[j] = queue[k];
- queue[k] = tmp;
- 317 k = j;
- 318
- }
- 319
- }
- 320 321 //排序(将nextExecutionTime最小的排到1位置) 在快速删除任务后调用
- 322 void heapify() {
- 323
- for (int i = size / 2; i >= 1; i--) 324 fixDown(i);
- 325
- }
- 326
- }
来源: http://www.cnblogs.com/xiaotaoqi/p/6874713.html