JAVA代码定时避免重复,Java重复调度定时任务的几种方法

在java中想要使一些任务能够定时地执行,可以有以下几种方法。

1,使用java.util包的Timer和TimerTask类,这是比较简单的方法。写一个类继承TimerTask,覆盖run()方法,并在方法里面加入定时的任务,然后调用Timer对象的schedule(TimerTask task, long delay, long period)方法即可。具体的代码:

importjava.util.Timer;importjava.util.TimerTask;public classDemo extendsTimerTask{

@Overridepublic voidrun() {

//这里添加你需要定时执行的任务

System.out.println("timertask run!");}

public static voidmain(String[] args) {

Timer timer = newTimer();longdelay = 5000;//指定从当前时间延迟多久后开始执行定时的任务,单位是毫秒longperiod = 1000;//指定每次执行任务的间隔时间,单位是毫秒timer.schedule(new Demo(),delay,period);}

}

使用Timer的问题是如果添加了多个定时任务,那么所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。

2,使用java.util.concurrent.ScheduledExecutorService的scheduleWithFixedDelay或scheduleAtFixedRate方法。首先要写一个类实现runnable或callable接口,覆盖run()或call()方法,在方法里添加你要定时执行的任务。然后创建一个ScheduledExecutorService,调用定时方法。具体的实现如下:

importjava.util.concurrent.Executors;importjava.util.concurrent.ScheduledExecutorService;importjava.util.concurrent.TimeUnit;public classScheduledExecutorDemo implementsRunnable{

@Overridepublic voidrun() {

//这里添加你需要定时执行的任务

System.out.println("scheduled executor run!");}

public static voidmain(String[] args) {

//使用Excutors的静态方法创建一个线程池ScheduledExecutorService,数字代表线程池的大小。

//如果任务数量超过了这个数字,那么任务会在一个queue里等待执行

ScheduledExecutorService service = Executors.newScheduledThreadPool(5);longdelay = 5;//指定从当前时间延迟多久后开始执行定时的任务,时间单位可以在调用方法时指定longperiod = 1;//指定每次执行任务的时间间隔service.scheduleAtFixedRate(newScheduledExecutorDemo(),delay,period,TimeUnit.SECONDS);service.scheduleWithFixedDelay(newScheduledExecutorDemo(),delay,period,TimeUnit.SECONDS);}

}

scheduleAtFixedRate和scheduleWithFixedDelay区别在于:前者是每次执行任务都是在上一个任务开始之后固定的period间隔后开始,而后者则是每次执行任务时都是在上一个任务结束后的period时间后才开始,即后者的任务开始执行的间隔不是固定的,会受到实际任务的执行时间波动。

3,使用ScheduledExecutorService的schedule()方法

上面两种创建定时任务的方法都比较简洁,但是也有一定的缺点,那就是无法在外部控制定时任务的开启和关闭,而且定时的时间也是写死的,不利于后期的维护。所以这里介绍一下第三种方式。我们知道,ScheduledExecutorService类的schedule(Callable call,long delay, TimeUnit unit)方法是让指定的Callable任务call在指定的时间delay延迟后执行,那么我们只要在任务类call的run()方法中使用schedule()方法并传递自身的引用,就可以形成循环调用,让这个任务过一段时间之后重新执行自身。为了解耦,这个任务类还需要有开启和关闭任务、指定延迟时间的接口。详细代码如下:

importjava.util.concurrent.Callable;importjava.util.concurrent.Executors;importjava.util.concurrent.ScheduledExecutorService;importjava.util.concurrent.TimeUnit;

public classMyCallable implementsCallable {

privateScheduledExecutorService scheduledExecutorService= Executors.newScheduledThreadPool(5);private longtimeDelay= 5;

public voidexcute(){

scheduledExecutorService.submit(this);}

public voidstop(){

scheduledExecutorService.shutdown();}

public voidsetTimeDelay(longtimeDelay){

this.timeDelay= timeDelay;}

@OverridepublicObject call() throwsException {

//一些业务逻辑,也就是你要循环执行的代码

System.out.println("my call Executed!");scheduledExecutorService.schedule(this,timeDelay,TimeUnit.SECONDS);return"Called!";}

}

执行这个循环任务的简单示例如下:

public static voidmain(String[] args) throwsException{

MyCallable call = newMyCallable();call.setTimeDelay(1);//指定定时执行的时间间隔call.excute();//执行任务Thread.sleep(10000);//让主线程等待一定时间call.stop();//关闭任务}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值