使用
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
Long temp = System.currentTimeMillis();
sync(updateTime);
updateTime = temp;
ConfigUtil.writeToFile("/updateTime.json",
LocalDateTime.ofInstant(
Instant.ofEpochMilli(updateTime), TimeZone.getDefault().toZoneId()).toString());
} catch (IOException e) {
e.printStackTrace();
}
ConsoleUtil.header2("休息中,400s后开始");
}
},
100000, 400000);
大概原理
有一个队列放着所有的task,然后有一个线程检测task是否到点,如果到点了就执行,否则就wait(相应时间).
public class TimerThread extends Thread {
private TaskQueue queue;
public void run() {
try {
mainLoop();
} finally {
// Someone killed this Thread, behave as if Timer cancelled
synchronized(queue) {
newTasksMayBeScheduled = false;
queue.clear(); // Eliminate obsolete references
}
}
}
/**
* The main timer loop. (See class comment.)
*/
private void mainLoop() {
while (true) {
try {
TimerTask task;
boolean taskFired;
synchronized(queue) {
// Wait for queue to become non-empty
while (queue.isEmpty() && newTasksMayBeScheduled)
queue.wait();
if (queue.isEmpty())
break; // Queue is empty and will forever remain; die
// Queue nonempty; look at first evt and do the right thing
long currentTime, executionTime;
task = queue.getMin();
synchronized(task.lock) {
if (task.state == TimerTask.CANCELLED) {
queue.removeMin();
continue; // No action required, poll queue again
}
currentTime = System.currentTimeMillis();
executionTime = task.nextExecutionTime;
if (taskFired = (executionTime<=currentTime)) {
if (task.period == 0) { // Non-repeating, remove
queue.removeMin();
task.state = TimerTask.EXECUTED;
} else { // Repeating task, reschedule
queue.rescheduleMin(
task.period<0 ? currentTime - task.period
: executionTime + task.period);
}
}
}
if (!taskFired) // Task hasn't yet fired; wait
//这里调用wait等待,也就会占用着锁,那么这个循环就无法再次进入.
queue.wait(executionTime - currentTime);
}
if (taskFired) // Task fired; run it, holding no locks
task.run();
} catch(InterruptedException e) {
}
}
}
}
评论区