ScheduledThreadPoolExecutor源码分析

概述

ScheduledThreadPoolExecutor可以用来在给定延时后执行异步任务或者周期性执行任务,相对于任务调度的Timer来说,其功能更加强大,Timer只能使用一个后台线程执行任务,而ScheduledThreadPoolExecutor则可以通过构造函数来指定后台线程的个数。

该类通过以下特性实现了ThreadPoolExecutor的拓展:

  • 使用自定义的FutureTask —— ScheduledFutureTask。
  • 使用自定义队列 —— DelayedWorkQueue。它是一个无边界的DelayedQueue的变体。
  • 支持可选的run-after-shutdown参数。可以重写shutdown方法,用以删除或者取消在执行shutdown方法后还没有运行的task。
  • task的装饰方法,用以拦截和装饰。因为子类无法通过重写shubmit方法来获得这个效果。

ScheduledThreadPoolExecutor处理的task分为以下2种类型:

  • periodic task:周期性执行的任务
  • one-shot delayed task:延迟执行的一次性任务

 

源码分析

延迟执行delayed task的schedule方法

根据指定的时间延迟和时间单位,将task加入线程池延迟执行。

/**
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public ScheduledFuture<?> schedule(Runnable command,
                                       long delay,
                                       TimeUnit unit) {
        if (command == null || unit == null)
            throw new NullPointerException();
        RunnableScheduledFuture<?> t = decorateTask(command,
            new ScheduledFutureTask<Void>(command, null,
                                          triggerTime(delay, unit)));
        delayedExecute(t);
        return t;
    }

处理periodic task的scheduleAtFixedRate方法

根据指定的时间延迟、时间周期和时间单位,将task加入线程池延迟执行。

该方法按指定频率周期执行某个任务。例如,初始化延迟0ms开始执行,每隔100ms重新执行一次任务。

    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit) {
        if (command == null || unit == null)
            throw new NullPointerException();
        if (period <= 0)
            throw new IllegalArgumentException();
        ScheduledFutureTask<Void> sft =
            new ScheduledFutureTask<Void>(command,
                                          null,
                                          triggerTime(initialDelay, unit),
                                          unit.toNanos(period));
        RunnableScheduledFuture<Void> t = decorateTask(command, sft);
        sft.outerTask = t;
        delayedExecute(t);
        return t;
    }

处理periodic task的scheduleWithFixedDelay方法

根据指定的初始时间延迟、时间间隔和时间单位,将task加入线程池延迟执行。

该方法按指定频率间隔执行某个任务。例如,初始化时延时0ms开始执行,本次执行结束后延迟100ms开始下次执行。

public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                     long initialDelay,
                                                     long delay,
                                                     TimeUnit unit) {
        if (command == null || unit == null)
            throw new NullPointerException();
        if (delay <= 0)
            throw new IllegalArgumentException();
        ScheduledFutureTask<Void> sft =
            new ScheduledFutureTask<Void>(command,
                                          null,
                                          triggerTime(initialDelay, unit),
                                          unit.toNanos(-delay));
        RunnableScheduledFuture<Void> t = decorateTask(command, sft);
        sft.outerTask = t;
        delayedExecute(t);
        return t;
    }

 delayedExecute()方法

处理delayed task或者periodic task的主要execute方法。如果线程池是shutdown的,拒绝task加入线程池,否则将线程池加入队列中,并启动一个线程,必要时执行它。如果在task加入队列后时线程池shut down了,根据run-after-shutdown参数和状态决定是否取消和删除这个task。

   private void delayedExecute(RunnableScheduledFuture<?> task) {
        if (isShutdown())
            reject(task);
        else {
            super.getQueue().add(task);
            if (isShutdown() &&
                !canRunInCurrentRunState(task.isPeriodic()) &&
                remove(task))
                task.cancel(false);
            else
                ensurePrestart();
        }
    }

ensurePrestart()方法

 /**
     * Same as prestartCoreThread except arranges that at least one
     * thread is started even if corePoolSize is 0.
     */
    void ensurePrestart() {
//获取线程池中的当前线程数
        int wc = workerCountOf(ctl.get());
        if (wc < corePoolSize)
            addWorker(null, true);
        else if (wc == 0)
            addWorker(null, false);
    }

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值