定时任务Java实现

定时任务Java实现的几种基本方法。

方法一:Thread

是我们最容易想到的,利用while循环,在其中加入sleep方法来实现定时功能。具体代码实现如下

代码示例:

public class TestTimeOrder {
    public static void main(String[] args) {
        final long timeInterval = 3000;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println(Thread.currentThread().getName() + " 定时间隔3秒");
                    try {
                        Thread.sleep(timeInterval);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }
}

方法二:Timer

考虑利用Timer类来调度任务,Timer实例可以调度多个任务,且是线程安全的。TimerTask在run方法中实现具体的任务要求。

该方法可以在第一次执行任务时设置延迟时间;且可以控制启动和取消任务。

注意:

使用 Timer 实现任务调度的核心类是 Timer 和 TimerTask。其中 Timer 负责设定 TimerTask 的起始与间隔执行时间。使用者只需要创建一个 TimerTask 的继承类,实现自己的 run 方法,然后将其丢给 Timer 去执行即可。Timer 的设计核心是一个 TaskList 和一个 TaskThread。Timer 将接收到的任务丢到自己的 TaskList 中,TaskList 按照 Task 的最初执行时间进行排序。TimerThread 在创建 Timer 时会启动成为一个守护线程。这个线程会轮询所有任务,找到一个最近要执行的任务,然后休眠,当到达最近要执行任务的开始时间点,TimerThread 被唤醒并执行该任务。之后 TimerThread 更新最近一个要执行的任务,继续休眠。

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

代码示例:

public class TestTimeOrder {
    public static void main(String[] args) {
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " 定时间隔3秒");
            }
        };
        Timer t = new Timer();
        long delay = 1000;
        long intevalTime = 3000;
        t.scheduleAtFixedRate(task, delay, intevalTime);
//        t.schedule(task,delay);
    }
}

方法三(也是最推荐的用法):线程池

该方法是通过线程池来执行任务实现的,主要是通过ScheduledExecutorService#scheduleAtFixedRate来实现任务运行和定时控制;好处是可以灵活设定第一次执行任务的delay时间以及提供了约定便于设定执行的时间间隔。相比于方法二,Timer是单线程的,该方法是通过线程池技术来实现。可以仔细研究下ScheduledExecutorService的用法。

其设计思想是,每一个被调度的任务都会由线程池中一个线程去执行,因此任务是并发执行的,相互之间不会受到干扰。需 要注意的是,只有当任务的执行时间到来时,ScheduedExecutor 才会真正启动一个线程,其余时间 ScheduledExecutor 都是在轮询任务的状态。

ScheduledExecutorService 中两种最常用的调度方法 ScheduleAtFixedRate 和 ScheduleWithFixedDelay。ScheduleAtFixedRate 每次执行时间为上一次任务开始起向后推一个时间间隔,即每次执行时间为 :initialDelayinitialDelay+periodinitialDelay+2*period, … ScheduleWithFixedDelay每次执行时间为上一次任务结束起向后推一个时间间隔,即每次执行时间为:initialDelayinitialDelay+executeTime+delayinitialDelay+2*executeTime+2*delay。由此可见,ScheduleAtFixedRate 是基于固定时间间隔进行任务调度,ScheduleWithFixedDelay 取决于每次任务执行的时间长短,是基于不固定时间间隔进行任务调度。

代码示例:

public class TestTimeOrder {
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " : 延迟1秒,间隔3秒");
            }
        };
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        service.scheduleAtFixedRate(runnable, 1000L, 3000L, TimeUnit.MILLISECONDS);
//        service.schedule(runnable,100L,TimeUnit.MILLISECONDS);
    }
}

以上是用Java方法实现的任务定时运行功能,主要涉及到了线程运行的知识,而且定时时间都是固定比较呆板的。仅供大家参考。如果想要实现复杂的定时功能,比方说,每周一上午10点运行。可以结合Calendar 来实现复杂任务的调度。具体应用方法可参考下文:

如何用 Java 实现 Web 应用中的定时任务

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值