任务调度的 Java 实现方法一:Timer、TimerTask、 ScheduledExecutorService

1.普通线程Thread

Runnable runnable = new Runnable() {
			
	@Override
	public void run() {
		while(true){
					
			System.out.println("hello world!!");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
};
		
Thread thread = new Thread(runnable);
thread.start()

2.Timer是一个定时器类,通过该类可以为指定的定时任务进行配置。

TimerTask类是一个定时任务类,该类实现了Runnable接口,而且是一个抽象类( public abstract class TimerTask implements Runnable ),

可以通过继承该类,来实现自己的定时任务。  

Timer定时器实例有多种构造方法:

  Timer()  创建一个新计时器。

  Timer(boolean isDaemon)  创建一个新计时器,可以指定其相关的线程作为守护程序运行。

  Timer(String name)  创建一个新计时器,其相关的线程具有指定的名称。

  Timer(String name, boolean isDaemon)  创建一个新计时器,其相关的线程具有指定的名称,并且可以指定作为守护程序运行。

定时执行方法
1、在特定时间执行任务,只执行一次
public void schedule(TimerTask task,Date time)

2、在特定时间之后执行任务,只执行一次
public void schedule(TimerTask task,long delay)

3、指定第一次执行的时间,然后按照间隔时间,重复执行
public void schedule(TimerTask task,Date firstTime,long period)

4、在特定延迟之后第一次执行,然后按照间隔时间,重复执行
public void schedule(TimerTask task,long delay,long period)
参数:delay: 延迟执行的毫秒数,即在delay毫秒之后第一次执行   period:重复执行的时间间隔
 
5、第一次执行之后,特定频率执行,与3同
public void scheduleAtFixedRate(TimerTask task,Date firstTime,long period)

6、在delay毫秒之后第一次执行,后按照特定频率执行
public void scheduleAtFixedRate(TimerTask task,long delay,long period)

7、注销
public void cancel()

TimerTask task = new TimerTask() {
			
	@Override
	public void run() {
		System.out.println("hello world!!");
	}
}; 
		
Timer timer = new Timer();
timer.scheduleAtFixedRate(task, 5000, 2000);

Timer 的设计核心是一个 TaskList 和一个 TaskThread。Timer 将接收到的任务丢到自己的 TaskList 中,TaskList 按照 Task 的最初执行时间进行排序。TimerThread 在创建 Timer 时会启动成为一个守护线程。这个线程会轮询所有任务,找到一个最近要执行的任务,然后休眠,当到达最近要执行任务的开始时间点,TimerThread 被唤醒并执行该任务。之后 TimerThread 更新最近一个要执行的任务,继续休眠。

Timer 的优点在于简单易用,但由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。

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

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

 3.接口ScheduleExecutorService原型定义

java.util.concurrent.ScheduleExecutorService extends ExecutorService extends Executor

常用方法:

1.schedule(Callable<V> callable, long delay, TimeUnit unit)

创建并执行在给定延迟后启用的 ScheduledFuture。用来延迟指定时间后执行某个指定任务。

2.schedule(Runnable command, long delay, TimeUnit unit)

安排所提交的Callable或Runnable任务在initDelay指定的时间后执行。

3.scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

安排所提交的Runnable任务按指定的间隔重复执行

4.scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)

安排所提交的Runnable任务在每次执行完后,等待delay所指定的时间后重复执行。

ScheduledExecutorService Service = Executors.newScheduledThreadPool(2);
final ScheduledFuture future1 = Service.schedule(new Runnable() {			
	@Override
	public void run() {				
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}				
		System.out.println("task is doing !! now is: " + format.format(new Date()));
	}
}, 1, TimeUnit.SECONDS);				
ScheduledFuture<String> future2 = Service.schedule(new Callable<String>() {

	@Override
	public String call() throws Exception {
		future1.cancel(true);
		System.out.println("future1 is canceled!!");
		return "i get you!! now is: " + format.format(new Date());
	}
}, 15, TimeUnit.SECONDS);
		
try {
	System.out.println(future2.get());
} catch (InterruptedException e) {
	e.printStackTrace();
} catch (ExecutionException e) {
	e.printStackTrace();
}				
Service.shutdown();

ScheduledExecutorService Service = Executors.newScheduledThreadPool(2);
Service.scheduleAtFixedRate(new Runnable() {			
	@Override
	public void run() {				
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}				
			System.out.println("task1 is doing !! now is: " + format.format(new Date()));
		}
}, 4, 3, TimeUnit.SECONDS);
				
Service.scheduleWithFixedDelay(new Runnable() {			
	@Override
	public void run() {			
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}				
			System.out.println("task2 is doing !! now is: " + format.format(new Date()));
	}
}, 4, 3, TimeUnit.SECONDS);


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值