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独自のタスクスケジューリングを実現するソリューションです.