Timer

Timer

Timer类主要负责计划任务的功能,也就是在指定的时间开始某一个任务。

Timer类主要作用就是设置计划任务,但封装任务的类确实TimerTask类。(TimerTask是一个抽象类,所以执行计划任务的代码要放进去TimerTask的子类中)

schedule(TimerTask task,Date time)

该方法的作用是在指定的日期执行一次某一任务。

执行任务的时间晚于当前时间:在未来执行的效果

例子:

public class Schedule {
	private static Timer timer=new Timer();
	public static void main(String[] args) {
		MyTask task=new MyTask();
		DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime localDateTime=LocalDateTime.parse("2018-10-28 19:16:00",df);
		ZoneId zoneId = ZoneId.systemDefault();        
		ZonedDateTime zdt = localDateTime.atZone(zoneId);
		Date date = Date.from(zdt.toInstant());
		System.out.println("执行时间:"+date+",当前时间:"+new Date());
		timer.schedule(task, date);
	}
}

class MyTask extends TimerTask{

	@Override
	public void run() {
		System.out.println("运行了!时间为:"+new Date());
	}
	
}

结果:
执行时间:Sun Oct 28 19:16:00 CST 2018,当前时间:Sun Oct 28 19:15:43 CST 2018
运行了!时间为:Sun Oct 28 19:16:00 CST 2018

这样的方式是一个新的线程,并不是守护线程,所以导致就算执行完任务,但是进程还没销毁。

解决方法:

private static Timer timer=new Timer(true);
计划时间早于当前时间:提前运行的效果

例子:

/** 
* @author 作者 E-mail: 
* @version 创建时间:2018年10月28日 下午7:03:26 
* 类说明 
*/
public class Schedule {
	private static Timer timer=new Timer(true);
	public static void main(String[] args) {
		MyTask task=new MyTask();
		DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime localDateTime=LocalDateTime.parse("2018-10-28 19:16:00",df);
		ZoneId zoneId = ZoneId.systemDefault();        
		ZonedDateTime zdt = localDateTime.atZone(zoneId);
		Date date = Date.from(zdt.toInstant());
		System.out.println("执行时间:"+date+",当前时间:"+new Date());
		timer.schedule(task, date);
	}
}

class MyTask extends TimerTask{

	@Override
	public void run() {
		System.out.println("运行了!时间为:"+new Date());
	}
	
}

结果为:
执行时间:Sun Oct 28 19:16:00 CST 2018,当前时间:Sun Oct 28 19:18:40 CST 2018
运行了!时间为:Sun Oct 28 19:18:40 CST 2018
多个TimerTask任务及延时的测试

例子:

public class Schedule2 {
	private static Timer timer=new Timer();
	public static void main(String[] args) {
		MyTask task1=new MyTask();
		MyTask task2=new MyTask();
		DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime localDateTime1=LocalDateTime.parse("2018-10-28 19:32:30",df);
		LocalDateTime localDateTime2=LocalDateTime.parse("2018-10-28 19:33:00",df);
		ZoneId zoneId = ZoneId.systemDefault();        
		ZonedDateTime zdt = localDateTime1.atZone(zoneId);
		Date date1 = Date.from(zdt.toInstant());
		zdt = localDateTime2.atZone(zoneId);
		Date date2 = Date.from(zdt.toInstant());
		System.out.println("任务1:执行时间:"+date1+",当前时间:"+new Date());
		System.out.println("任务2:执行时间:"+date2+",当前时间:"+new Date());
		timer.schedule(task1, date1);
		timer.schedule(task2, date2);
	}
}

class MyTask extends TimerTask{

	@Override
	public void run() {
		System.out.println("运行了!时间为:"+new Date());
	}
	
}

结果:
任务1:执行时间:Sun Oct 28 19:32:30 CST 2018,当前时间:Sun Oct 28 19:32:12 CST 2018
任务2:执行时间:Sun Oct 28 19:33:00 CST 2018,当前时间:Sun Oct 28 19:32:12 CST 2018
运行了!时间为:Sun Oct 28 19:32:30 CST 2018
运行了!时间为:Sun Oct 28 19:33:00 CST 2018

TimerTask是以队列的方式一个一个被顺序执行的,所以执行的时间有可能和预期的时间不一致,因为假如前面的任务消耗的时间较长,则后面的任务运行的时间也会被延迟。

如下:

public class Schedule2 {
	private static Timer timer=new Timer();
	public static void main(String[] args) {
		MyTask task1=new MyTask();
		MyTask task2=new MyTask();
		DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime localDateTime1=LocalDateTime.parse("2018-10-28 19:37:00",df);
		LocalDateTime localDateTime2=LocalDateTime.parse("2018-10-28 19:37:05",df);
		ZoneId zoneId = ZoneId.systemDefault();        
		ZonedDateTime zdt = localDateTime1.atZone(zoneId);
		Date date1 = Date.from(zdt.toInstant());
		zdt = localDateTime2.atZone(zoneId);
		Date date2 = Date.from(zdt.toInstant());
		System.out.println("任务1:执行时间:"+date1+",当前时间:"+new Date());
		System.out.println("任务2:执行时间:"+date2+",当前时间:"+new Date());
		timer.schedule(task1, date1);
		timer.schedule(task2, date2);
	}
}

class MyTask extends TimerTask{

	@Override
	public void run() {
		System.out.println("start时间为:"+new Date());
		try {
			Thread.sleep(20000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("end时间为:"+new Date());
	}
	
}

结果为:
任务1:执行时间:Sun Oct 28 19:37:00 CST 2018,当前时间:Sun Oct 28 19:36:30 CST 2018
任务2:执行时间:Sun Oct 28 19:37:05 CST 2018,当前时间:Sun Oct 28 19:36:30 CST 2018
start时间为:Sun Oct 28 19:37:00 CST 2018
end时间为:Sun Oct 28 19:37:20 CST 2018
start时间为:Sun Oct 28 19:37:20 CST 2018
end时间为:Sun Oct 28 19:37:40 CST 2018

schedule(TimerTask task,Date firstTime,long period)

该方法的作用是在指定的日期之后,按指定的间隔周期性地无限循环地执行某一任务

public class Schedule2 {
	private static Timer timer=new Timer();
	public static void main(String[] args) {
		MyTask task1=new MyTask();
		DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime localDateTime1=LocalDateTime.parse("2018-10-28 19:43:00",df);
		ZoneId zoneId = ZoneId.systemDefault();        
		ZonedDateTime zdt = localDateTime1.atZone(zoneId);
		Date date1 = Date.from(zdt.toInstant());
		System.out.println("任务1:执行时间:"+date1+",当前时间:"+new Date());
		timer.schedule(task1, date1,2000);
	}
}

class MyTask extends TimerTask{

	@Override
	public void run() {
		System.out.println("执行了!时间为:"+new Date());
	}
	
}

结果为:
任务1:执行时间:Sun Oct 28 19:43:00 CST 2018,当前时间:Sun Oct 28 19:42:49 CST 2018
执行了!时间为:Sun Oct 28 19:43:00 CST 2018
执行了!时间为:Sun Oct 28 19:43:02 CST 2018
执行了!时间为:Sun Oct 28 19:43:04 CST 2018
执行了!时间为:Sun Oct 28 19:43:06 CST 2018
执行了!时间为:Sun Oct 28 19:43:08 CST 2018
执行了!时间为:Sun Oct 28 19:43:10 CST 2018

TimerTask的cancel()与Timer的cancel()

TimerTask的cancel()是将自身从任务队列中移除,其他任务不受影响

Timer的cancel()是全部任务都被清除,并且进程被销毁。(ps:Timer类中的cancel()方法有时争抢不到queue锁,就停止不了执行任务)

public class Schedule2 {
	private static Timer timer=new Timer();
	public static void main(String[] args) {
		MyTask1 task1=new MyTask1();
		MyTask2 task2=new MyTask2();
		DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime localDateTime1=LocalDateTime.parse("2018-10-28 19:37:00",df);
		LocalDateTime localDateTime2=LocalDateTime.parse("2018-10-28 19:37:05",df);
		ZoneId zoneId = ZoneId.systemDefault();        
		ZonedDateTime zdt = localDateTime1.atZone(zoneId);
		Date date1 = Date.from(zdt.toInstant());
		zdt = localDateTime2.atZone(zoneId);
		Date date2 = Date.from(zdt.toInstant());
		System.out.println("任务1:执行时间:"+date1+",当前时间:"+new Date());
		System.out.println("任务2:执行时间:"+date2+",当前时间:"+new Date());
		timer.schedule(task1, date1,2000);
		timer.schedule(task2, date2,2000);
		try {
			Thread.sleep(10000);
			//timer的cancel()
			timer.cancel();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

class MyTask1 extends TimerTask{
	@Override
	public void run() {
		System.out.println("MyTask1为:"+new Date());
		//timerTask的cancel()
		this.cancel();
	}
}
class MyTask2 extends TimerTask{
	@Override
	public void run() {
		System.out.println("MyTask2为:"+new Date());
	}
}

结果:
任务1:执行时间:Sun Oct 28 19:37:00 CST 2018,当前时间:Sun Oct 28 19:49:47 CST 2018
任务2:执行时间:Sun Oct 28 19:37:05 CST 2018,当前时间:Sun Oct 28 19:49:47 CST 2018
MyTask1为:Sun Oct 28 19:49:47 CST 2018
MyTask2为:Sun Oct 28 19:49:47 CST 2018
MyTask2为:Sun Oct 28 19:49:49 CST 2018
MyTask2为:Sun Oct 28 19:49:51 CST 2018
MyTask2为:Sun Oct 28 19:49:53 CST 2018
MyTask2为:Sun Oct 28 19:49:55 CST 2018

之后就结束了,进程也销毁了。

Timer的cancel()停止不了(每次都new一次):

public class Schedule2 {
	public static void main(String[] args) {
		while(true){
			Timer timer=new Timer();
			MyTask1 task1=new MyTask1();
			DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
			LocalDateTime localDateTime1=LocalDateTime.parse("2018-10-28 19:37:00",df);
			ZoneId zoneId = ZoneId.systemDefault();        
			ZonedDateTime zdt = localDateTime1.atZone(zoneId);
			Date date1 = Date.from(zdt.toInstant());
			timer.schedule(task1, date1);
			timer.cancel();
		}
	}
}

class MyTask1 extends TimerTask{
	@Override
	public void run() {
		System.out.println("MyTask1为:"+new Date());
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值