Java定时任务

http://blog.csdn.net/xyang81/article/details/7425943

 

在日常工作中,定时进行任务调度的业务随处可见,比如:定时清理系统的临时文件、有新的活动定时向用户发送电子邮件、定时检查系统是否需要更新、定时发送短信等业务。在Java中由两个类完成定时任务的调度,分别为:java.util.Timer和java.util.TimerTask

创建一个定时任务的步聚:

1、创建一个定时器(Timer)对象

2、调用该对象的schedule(TimerTask task, long delay, long period)scheduleAtFixedRate(TimerTask task, long delay, long period)方法


任务调度方法参数说明:

task:表示要执行的具体任务

delay表示任务创建完成后,第一次什么时候开始执行该任务,以毫秒为单位

period:表示第一次执行完任务后,后续重复执行该任务的时间间隔是多长,以毫秒为单位


schedule方法与scheduleAtFixedRate方法的区别:

 

方法任务执行时间当任务执行时间大于间隔时间时
schedule上次任务的结束时间+时间间隔阻塞式,任务会延后,等待前面的任务执行完,再执行延务后的任务
scheduleAtFixedRate上次任务的执行时间+时间间隔任务不会延后,但要考虑多线程并发的问题。因为当一个任务还没执行完时,下一个时间间隔任务又会启动,执行相同的任务


 

注意:每启动一个新任务,就会启动一个新的线程!


实例:

  1. package taskschedule; 
  2.  
  3. import java.text.SimpleDateFormat; 
  4. import java.util.Calendar; 
  5. import java.util.Timer; 
  6. import java.util.TimerTask; 
  7.  
  8. /*
  9. * 定时器
  10. *
  11. * schedule():下一次任务的执行时间,等于上一次任务的结束时间+时间间隔
  12. *
  13. * scheduleAtFixedRate():下一次任务的执行时间,等于上一次任务的开始时间+时间间隔
  14. *
  15. * 当执行任务的时间大于时间间隔时:
  16. * schedule任务会延后。
  17. * scheduleAtFixedRate任务不会延后,仍然在时间间隔内执行,存在并发性,要考虑线程同步的问题
  18. */ 
  19. public class TimerTest { 
  20.      
  21.     private static int count = 0
  22.      
  23.     public static void main(String[] args) { 
  24.         task_1(); 
  25.          
  26.         //task_2(); 
  27.          
  28.         //task_3(); 
  29.          
  30.         //task_4(); 
  31.          
  32.         //主线程 
  33.         while(true) { 
  34.             System.out.println(Calendar.getInstance().get(Calendar.SECOND)); 
  35.             try
  36.                 Thread.sleep(1000); 
  37.             } catch (InterruptedException e) { 
  38.                 e.printStackTrace(); 
  39.             } 
  40.         } 
  41.     } 
  42.      
  43.     //任务1:第一次延迟3秒后启动任务,后续每隔2秒启动一次任务 
  44.     private static void task_1() { 
  45.         new Timer().schedule(new TimerTask(){ 
  46.  
  47.             @Override 
  48.             public void run() { 
  49.                 System.out.println(Thread.currentThread().getName() + "定时任务已启动!"); 
  50.                  
  51.             }}, 3000,2000);  
  52.     } 
  53.      
  54.     //任务2:交互执行,方式1:第一次延迟2秒后启动任务,后续每隔在3秒和6秒之间切换启动任务 
  55.     private static void task_2() { 
  56.         class MyTimerTask extends TimerTask { 
  57.              
  58.             @Override 
  59.             public void run() { 
  60.                 count = (count+1)%2
  61.                 System.out.println(Thread.currentThread().getName() + "定时任务已启动!"); 
  62.                  
  63.                 new Timer().schedule(new MyTimerTask(), 3000 + 3000 * count);   //循环调用 
  64.             } 
  65.         } 
  66.          
  67.         new Timer().schedule(new MyTimerTask(), 2000);  //2秒后启动定时器 
  68.     } 
  69.      
  70.     //任务3:交互执行,方式2:第一次延迟2秒后启动任务,后续每隔在3秒和6秒之间切换启动任务 
  71.     public static void task_3() { 
  72.         new Timer().schedule(new MyTimerTaskA(), 300); 
  73.     } 
  74.      
  75.     //任务4:演示scheduleAtFixedRate方法,第一次延迟2秒后启动任务,后续每隔3秒后启动任务,但任务执行时间大于等于6秒 
  76.     public static void task_4() { 
  77.         TimerTask task = new TimerTask(){ 
  78.  
  79.             @Override 
  80.             public void run() { 
  81.                 System.out.println("execute task:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime())); 
  82.                 try
  83.                     Thread.sleep(6000); 
  84.                 } catch (InterruptedException e) { 
  85.                     e.printStackTrace(); 
  86.                 } 
  87.                 System.out.println(Thread.currentThread().getName() + "定时任务已启动!"); 
  88.             } 
  89.         }; 
  90.          
  91.         new Timer().scheduleAtFixedRate(task, 2000, 3000); 
  92.     } 
  93.  
  94. //描述2个任务切换启动 
  95. class MyTimerTaskA extends TimerTask { 
  96.  
  97.     @Override 
  98.     public void run() { 
  99.         System.out.println(Thread.currentThread().getName() + "任务已启动!"); 
  100.         new Timer().schedule(new MyTimerTaskB(),2000); 
  101.     } 
  102.      
  103.  
  104. class MyTimerTaskB extends TimerTask { 
  105.      
  106.     @Override 
  107.     public void run() { 
  108.         System.out.println(Thread.currentThread().getName() + "任务已启动!"); 
  109.         new Timer().schedule(new MyTimerTaskA(), 4000); 
  110.     } 
  111.      
package taskschedule;

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

/*
 * 定时器
 * 
 * schedule():下一次任务的执行时间,等于上一次任务的结束时间+时间间隔
 * 
 * scheduleAtFixedRate():下一次任务的执行时间,等于上一次任务的开始时间+时间间隔
 * 
 * 当执行任务的时间大于时间间隔时:
 * schedule任务会延后。
 * scheduleAtFixedRate任务不会延后,仍然在时间间隔内执行,存在并发性,要考虑线程同步的问题
 */
public class TimerTest {
	
	private static int count = 0;
	
	public static void main(String[] args) {
		task_1();
		
		//task_2();
		
		//task_3();
		
		//task_4();
		
		//主线程
		while(true) {
			System.out.println(Calendar.getInstance().get(Calendar.SECOND));
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	//任务1:第一次延迟3秒后启动任务,后续每隔2秒启动一次任务
	private static void task_1() {
		new Timer().schedule(new TimerTask(){

			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName() + "定时任务已启动!");
				
			}}, 3000,2000);	
	}
	
	//任务2:交互执行,方式1:第一次延迟2秒后启动任务,后续每隔在3秒和6秒之间切换启动任务
	private static void task_2() {
		class MyTimerTask extends TimerTask {
			
			@Override
			public void run() {
				count = (count+1)%2;
				System.out.println(Thread.currentThread().getName() + "定时任务已启动!");
				
				new Timer().schedule(new MyTimerTask(), 3000 + 3000 * count);	//循环调用
			}
		}
		
		new Timer().schedule(new MyTimerTask(), 2000);	//2秒后启动定时器
	}
	
	//任务3:交互执行,方式2:第一次延迟2秒后启动任务,后续每隔在3秒和6秒之间切换启动任务
	public static void task_3() {
		new Timer().schedule(new MyTimerTaskA(), 300);
	}
	
	//任务4:演示scheduleAtFixedRate方法,第一次延迟2秒后启动任务,后续每隔3秒后启动任务,但任务执行时间大于等于6秒
	public static void task_4() {
		TimerTask task = new TimerTask(){

			@Override
			public void run() {
				System.out.println("execute task:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime()));
				try {
					Thread.sleep(6000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + "定时任务已启动!");
			}
		};
		
		new Timer().scheduleAtFixedRate(task, 2000, 3000);
	}
}

//描述2个任务切换启动
class MyTimerTaskA extends TimerTask {

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + "任务已启动!");
		new Timer().schedule(new MyTimerTaskB(),2000);
	}
	
}

class MyTimerTaskB extends TimerTask {
	
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + "任务已启动!");
		new Timer().schedule(new MyTimerTaskA(), 4000);
	}
	
}


任务执行结果:

任务1:


任务2:


任务3:


任务4:


但JDK提供的定时器任务功能有限,不能完成一些复杂的业务,比如:要每年单月的每周星期三的下午5点10分要执行一个任务,JDK则处理不了。不过不要担心,市面上已经有开源的任务调度框架:Quartz,官网:http://www.quartz-scheduler.org/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值