跳至主要內容

定时任务的简单实现

BlueCitizen...大约 4 分钟后端Java

说到定时任务,比较容易想到的是quartz定时框架。而一些简单轻量的任务使用框架未免杀鸡用牛刀了。我们也可以通过ScheduledExecutorService接口实现。

定时任务的简单实现

ScheduledExecutorService

Oracle文档open in new window

public interface ScheduledExecutorService extends ExecutorService

继承自接口ExecutorService,官方给出的说明:这是一个可以设定延时执行命令或定期循环执行的ExecutorService。

Timer

ScheduledExecutorService和Timer的区别在于,Timer的内部只有一个线程,如果有多个任务就变成顺序执行,我们设定的延迟时间和循环时间就不正确了。

ScheduledExecutorService是基于线程池设计的定时任务类,每个(循环)调度任务都会分配到线程池中的一个线程去执行,任务是并发执行,互不影响。

在对延迟任务和循环任务要求严格的时候,就需要考虑使用ScheduledExecutorService了。

需要注意,只有当调度任务来的时候,ScheduledExecutorService才会真正启动一个线程,其余时间ScheduledExecutorService都是出于轮询任务的状态。

schedule()

schedule方法源码:

/**
     * Creates and executes a one-shot action that becomes enabled
     * after the given delay.
     *
     * @param command the task to execute
     * @param delay the time from now to delay execution
     * @param unit the time unit of the delay parameter
     * @return a ScheduledFuture representing pending completion of
     *         the task and whose {@code get()} method will return
     *         {@code null} upon completion
     * @throws RejectedExecutionException if the task cannot be
     *         scheduled for execution
     * @throws NullPointerException if command is null
     */
    public ScheduledFuture<?> schedule(Runnable command,long delay, TimeUnit unit);

设定延时后单次执行动作,定义了三个参数:

  • Runnable类型的指令(任务)
  • long型的延时
  • TimeUnit值

用起来像这样:

    /**
     * 操作延迟10毫秒
     */
    private static final int OPERATE_DELAY_TIME = 10;

    /**
     * 执行任务
     *
     * @param task 任务
     */
    public void execute(TimerTask task) {
        scheduledExecutorService.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
    }

查看源码,TimerTask类是Runnable接口的实现,“一种可以计划执行一次或循环的定时器”。因此参数也是符合定义的。

//TimerTask类源码

package java.util;

/**
 * A task that can be scheduled for one-time or repeated execution by a Timer.
 *
 * @author  Josh Bloch
 * @see     Timer
 * @since   1.3
 */

public abstract class TimerTask implements Runnable
//Runnable接口源码

package java.lang;

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

scheduleAtFixedRate()

源码:

    /**
     * Creates and executes a periodic action that becomes enabled first
     * after the given initial delay, and subsequently with the given
     * period; that is executions will commence after
     * {@code initialDelay} then {@code initialDelay+period}, then
     * {@code initialDelay + 2 * period}, and so on.
     * If any execution of the task
     * encounters an exception, subsequent executions are suppressed.
     * Otherwise, the task will only terminate via cancellation or
     * termination of the executor.  If any execution of this task
     * takes longer than its period, then subsequent executions
     * may start late, but will not concurrently execute.
     *
     * @param command the task to execute
     * @param initialDelay the time to delay first execution
     * @param period the period between successive executions
     * @param unit the time unit of the initialDelay and period parameters
     * @return a ScheduledFuture representing pending completion of
     *         the task, and whose {@code get()} method will throw an
     *         exception upon cancellation
     * @throws RejectedExecutionException if the task cannot be
     *         scheduled for execution
     * @throws NullPointerException if command is null
     * @throws IllegalArgumentException if period less than or equal to zero
     */
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);

创建并执行一个首先被启用的周期性动作,按照上一次任务的发起时间计算下一次任务的开始时间。若执行发生异常,则立即停止并抑制后续执行。若任务用时超过间隔,则下一个任务等待正在执行的任务结束才能执行,因此不允许并发执行。定义了四个参数:

  • Runnable 待执行的指令(任务)
  • long 的初始化延时(第一次执行前的延时)
  • long 循环任务连续执行的间隔(按照上一次任务的发起时间计算下一次任务的开始时间)
  • TimeUnit值
/**
     * Creates and executes a periodic action that becomes enabled first
     * after the given initial delay, and subsequently with the
     * given delay between the termination of one execution and the
     * commencement of the next.  If any execution of the task
     * encounters an exception, subsequent executions are suppressed.
     * Otherwise, the task will only terminate via cancellation or
     * termination of the executor.
     *
     * @param command the task to execute
     * @param initialDelay the time to delay first execution
     * @param delay the delay between the termination of one
     * execution and the commencement of the next
     * @param unit the time unit of the initialDelay and delay parameters
     * @return a ScheduledFuture representing pending completion of
     *         the task, and whose {@code get()} method will throw an
     *         exception upon cancellation
     * @throws RejectedExecutionException if the task cannot be
     *         scheduled for execution
     * @throws NullPointerException if command is null
     * @throws IllegalArgumentException if delay less than or equal to zero
     */
    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);

和scheduleAtFixedRate()的区别是周期计算的基准变为从前一次执行结束到下一次执行开始的间隔。参数相同。

ThreadFactory

https://www.cnblogs.com/chenmo-xpw/p/5555931.html https://blog.csdn.net/u011315960/article/details/71422386

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3