java自带定时任务执行解决方案 Timer TimerTask源码分析

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。  也就是每一个小时派出去一个小弟去执行task。 子线程不结束。mian线程也无法结束。

就实现java自带任务调度的解决方案。




你可能感兴趣的:(java自带定时任务执行解决方案 Timer TimerTask源码分析)