JAva独自タイミングタスク実行ソリューションTimer TimerTaskソース分析
3968 ワード
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import dao.ExcelDao;
public class ReadExcel extends TimerTask {
private static ExcelDao dao = new ExcelDao();
public static void main(String[] args){
Timer timer = new Timer();
// , ,
int dat = 1*60*60*1000 ;
// int dat = 5*60*1000 ;
// , 4
// Calendar time=Calendar.getInstance();
// time.set(time.HOUR_OF_DAY, 20);
// time.set(time.MINUTE, 0);
// time.set(time.SECOND, 0);
//
// timer.schedule(new ReadExcel(), time.getTime(), dat);
//
timer.schedule(new ReadExcel(), 1000L, dat);
}
public void run() {
System.out.println(" run");
}
}
1、まず、Timerの実現を見てみましょう.
/*Timer */
private TaskQueue queue = new TaskQueue();
private TimerThread thread = new TimerThread(queue);
public Timer() {
this("Timer-" + serialNumber());
}
public Timer(String name) {
thread.setName(name);
thread.start();
}
ここから、Timerをインスタンス化する際に、TimerTheadというスレッドが開いていることがわかります.TimerThreadのrunメソッドを見てみましょう.
public void run() {
try {
mainLoop();
} finally {
// Someone killed this Thread, behave as if Timer cancelled
synchronized(queue) {
newTasksMayBeScheduled = false;
queue.clear(); // Eliminate obsolete references
}
}
}
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 queue,
timer.schedule(new ReadExcel(), 1000L, dat);
*/
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
queue.wait(executionTime - currentTime);
}
if (taskFired) // Task fired; run it, holding no locks
task.run(); // task run
} catch(InterruptedException e) {
}
}
}
}
mainLoopメソッドの役割は,主に1000ミリ秒が経過した後,最初のtaskを実行し始め,その後1時間が経過した後,このtaskのrunを実行することである.つまり1時間ごとに弟を派遣してtaskを実行します.サブスレッドは終了しません.mianスレッドも終了できません.
Java独自のタスクスケジューリングを実現するソリューションです.