java定时任务调度工具之Timer

本文深入解析 Java 中 Timer 类的功能及使用方法,包括 TimerTask 的创建、四种 schedule 方法的区别与应用场景,以及 scheduleAtFixedRate 方法的特点。同时探讨了 Timer 在并发场景下的局限性和使用禁区。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、定义:(祥见JDK文档)有且仅有一个后台线程对多个业务线程进行定时定频率的调度。

二、构件:Timer定时调用,TimerTask任务。

三、timer的schedule函数的四种用法:

       1.schdule(task,time)

              task:所要安排的任务。

             time:执行任务的时间。

             作用:在时间等于或者超过time的时候执行且仅执行一次task(当time晚于当前时间,后台线程等待,当time早于当前时间,启动后立即执行)。

       2.schdule(task,time,period)

              task:所要安排的任务。

              time:执行任务的时间。

              period:执行一次任务的时间间隔,单位是毫秒。

             作用:在时间等于或者超过time的时候首次执行task,之后每隔period毫秒重复执行一次task。

      3.schdule(task,delay)

              task:所要安排的任务。

             time:执行任务前的延迟时间,单位毫秒。

             作用:等待delay毫秒后执行且仅执行一次task。

       4.schdule(task,delay,period)

              task:所要安排的任务。

              delay:执行任务前的延迟时间,单位毫秒。

              period:执行一次任务的时间间隔,单位是毫秒。

             作用:等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task。

      5.schduleAtFixedRate(task,time,period)

              task:所要安排的任务。

              time:执行任务的时间。

              period:执行一次任务的时间间隔,单位是毫秒。

             作用:在时间等于或者超过time的时候首次执行task,之后每隔period毫秒重复执行一次task。

     6.schduleAtFixedRate(task,time,period)

              task:所要安排的任务。

              time:执行任务的时间。

              period:执行一次任务的时间间隔,单位是毫秒。

             作用:等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task。


import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;




public class MytimerTask extends TimerTask{
    private String name;//任务名称
    private AtomicInteger count = new AtomicInteger(0);//执行次数,线程安全
	public MytimerTask(String name){
		this.name = name;
	}
	public void run() {
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
		String time = format.format(calendar.getTime());
		
		//已安排的任务最近执行时间
		long nexttime = scheduledExecutionTime();
		System.out.println(name+"最近执行时间时间:"+ format.format(nexttime));
		//获取当前的值并自增
		count.getAndIncrement();
		System.out.println("执行"+count+"次"+name+"任务:"+ time);
		
		
		
		if(count.get()>=5){
			System.out.println("----"+name+"执行任务满五次取消任务----");
			//取消当前timerTask里面的任务
			cancel();
		}
		
	}

}

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

public class Mytimer{
	
     public static void main(String[] args) throws InterruptedException {
		Timer timer = new Timer();
		TimerTask myTask1 = new MytimerTask("myTask1");
		
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
		
		//获取当前时间
		Calendar calendar = Calendar.getInstance();
		System.out.println("启动定时器时间:"+dateFormat.format(calendar.getTime()));
		//当前时间的三秒钟后
		calendar.add(Calendar.SECOND, 3);
		//在时间等于或超过time的时候执行且仅执行一次任务
		timer.schedule(myTask1, calendar.getTime());
		
		TimerTask myTask2 = new MytimerTask("myTask2");
		
		Thread.sleep(5000);//休眠5s
		//在时间等于或在超过time时,首次执行task,之后每隔period毫秒,重复执行一次task
		timer.schedule(myTask2, calendar.getTime(), 3000);
		
		TimerTask myTask3 = new MytimerTask("myTask3");
		//等待delay毫秒后,执行且仅执行一次task
		timer.schedule(myTask3, 2000);
		
		//在等待delay毫秒后,首次执行task,之后每隔period毫秒,重复执行一次task
		TimerTask myTask4 = new MytimerTask("myTask4");
		timer.schedule(myTask4, 3000, 2000);
		
		Thread.sleep(5000);//休眠5s
		
		//在时间等于或在超过time时,首次执行task,之后每隔period毫秒,重复执行一次task
		TimerTask myTask5 = new MytimerTask("myTask5");
		timer.scheduleAtFixedRate(myTask5, calendar.getTime(), 2000);
		
		//在延迟delay毫秒后,首次执行task,之后每隔period毫秒执行一次task
		TimerTask myTask6 = new MytimerTask("myTask6");
		timer.scheduleAtFixedRate(myTask6, 2000, 3000);
		
		//从此计时器的任务队列中移除所有已取消的任务
		timer.purge();
		
		//丢弃当前所有已安排的任务
		timer.cancel();
		
		System.out.println("所有任务取消");
		
     }

}

scheduleAtFixedRate与schedule的区别:

    1.首次计划执行时间早于任务启动时间

           schedule方法:如果第一次执行时间被延迟了,随后的执行时间按照上一次实际执行完成的时间点进行计算

           scheduleAtFixedRate方法:如果第一次执行时间被延迟了,随后执行时间按照上一次开始时间点进行计算,并且为了赶上进度,会多次执行任务,因此TimerTask中的执行体需要考虑同步。

     2.执行任务时间超出执行周期的间隔

         schedule 方法:下一次执行时间相对于上一次实际完成的时间点,因此执行时间会不断延后

        scheduleAtFixedRate方法:下一次执行时间相对于上一次开始的时间点,因此执行时间一般不会延后,因此存在并发性

         

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

public class Mytimer{
	
     public static void main(String[] args) throws InterruptedException {
		Timer timer = new Timer();
		
		
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
		
		//获取当前时间
		Calendar calendar = Calendar.getInstance();
		System.out.println("启动定时器时间:"+dateFormat.format(calendar.getTime()));
		//当前时间的四秒钟之前
		calendar.add(Calendar.SECOND, -4);
		
		TimerTask myTask1 = new MytimerTask("myTask1");
		timer.schedule(myTask1, calendar.getTime(), 2000);
		
		TimerTask myTask2 = new MytimerTask("myTask2");
		timer.scheduleAtFixedRate(myTask2, calendar.getTime(), 2000);
	    
		
     }

}
   timer的缺陷:

    1. 管理并发任务的缺陷: timer有且仅有一个后台线程去执行定时任务,如果存在多个任务,且任务时间过长会导致执行效果与预期不符。

    2.当任务抛出异常时的缺陷:如果TimerTask抛出RuntimeException,timer会停止所有任务的运行

Timer的使用禁区:

   1.对时效性要求较高的任务并发作业

   2.对复杂任务的调度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值