详解java定时任务

 

详解java定时任务

第一种:利用Tiker和TimerTask

指定延迟时间执行定时任务

package com.huohg.Quartz;

import java.util.Timer;
import java.util.TimerTask;

public class TimerTest01 {
	Timer timer;  
    public TimerTest01(int time){  
        timer = new Timer();  
        timer.schedule(new TimerTaskTest01(), time * 1000);  
    }  
      
    public static void main(String[] args) {  
        System.out.println("timer begin....");  
        new TimerTest01(3);  
    }  
}  
  
class TimerTaskTest01 extends TimerTask{  
  
    public void run() {  
        System.out.println("Time's up!!!!");  
    }  
}

  运行结果:

 

在指定时间执行定时任务

package com.huohg.Quartz;

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
 * 在指定时间执行定时任务
 * 当时间到达16:21:00时就会执行该线程任务,当然大于该时间也会执行!!执行结果为:
 * */
public class TimerTest02 {  
    Timer timer;  
      
    public TimerTest02(){  
        Date time = getTime();  
        System.out.println("指定时间time=" + time);  
        timer = new Timer();  
        timer.schedule(new TimerTaskTest02(), time);  
    }  
      
    public Date getTime(){  
        Calendar calendar = Calendar.getInstance();  
        calendar.set(Calendar.HOUR_OF_DAY, 16);  
        calendar.set(Calendar.MINUTE, 21);  
        calendar.set(Calendar.SECOND, 00);  
        Date time = calendar.getTime();  
          
        return time;  
    }  
      
    public static void main(String[] args) {  
        new TimerTest02();  
    }  
}  
  
class TimerTaskTest02 extends TimerTask{  
  
    @Override  
    public void run() {  
        System.out.println("指定时间执行线程任务...");  
    }  
}  

  运行结果:

 

 

在延迟指定时间后以指定的间隔时间循环执行定时任务

package com.huohg.Quartz;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
 * 在延迟指定时间后以指定的间隔时间循环执行定时任务
 * */
public class TimerTest03 {  
    Timer timer;  
      
    public TimerTest03(){  
        timer = new Timer();  
        timer.schedule(new TimerTaskTest03(), 1000, 2000);  
    }  
      
    public static void main(String[] args) {  
        new TimerTest03();  
    }  
}  
  
 class TimerTaskTest03 extends TimerTask{  
  
    @Override  
    public void run() {  
        Date date = new Date(this.scheduledExecutionTime());  
        System.out.println("本次执行该线程的时间为:" + date);  
    }  
}  

 总结:

Timer计时器可以定时(指定时间执行任务)、延迟(延迟5秒执行任务)、周期性地执行任务(每隔个1秒执行任务),但是,Timer存在一些缺陷。首先Timer对调度的支持是基于绝对时间的,而不是相对时间,所以它对系统时间的改变非常敏感。其次Timer线程是不会捕获异常的,如果TimerTask抛出的了未检查异常则会导致Timer线程终止,同时Timer也不会重新恢复线程的执行,他会错误的认为整个Timer线程都会取消。同时,已经被安排单尚未执行的TimerTask也不会再执行了,新的任务也不能被调度。故如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。

 

解决问题:

对于Timer的缺陷,我们可以考虑 ScheduledThreadPoolExecutor 来替代。Timer是基于绝对时间的,对系统时间比较敏感,而ScheduledThreadPoolExecutor 则是基于相对时间;Timer是内部是单一线程,而ScheduledThreadPoolExecutor内部是个线程池,所以可以支持多个任务并发执行。

 

package com.huohg.Quartz;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/*
 * 替换 Timer定时任务
 * ScheduledExecutorService
 * 
 * **/
public class ScheduledExecutorTest {  
    private  ScheduledExecutorService scheduExec;  
      
    public long start;  
      
    ScheduledExecutorTest(){  
        this.scheduExec =  Executors.newScheduledThreadPool(2);    
        this.start = System.currentTimeMillis();  
    }  
      
    public void timerOne(){  
        scheduExec.schedule(new Runnable() {  
            public void run() {  
                throw new RuntimeException();  
            }  
        },1000,TimeUnit.MILLISECONDS);  
    }  
      
    public void timerTwo(){  
        scheduExec.scheduleAtFixedRate(new Runnable() {  
            public void run() {  
                System.out.println("timerTwo invoked .....");  
            }  
        },2000,500,TimeUnit.MILLISECONDS);  
    }  
      
    public static void main(String[] args) {  
        ScheduledExecutorTest test = new ScheduledExecutorTest();  
        test.timerOne();  
        test.timerTwo();  
    }  
}  

 

posted @ 2017-06-30 16:30  技术专家  阅读(343)  评论(0编辑  收藏  举报