• JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor


    JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor

    ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor。它主要用来在给定的延迟之后运行任务,或者定期执行任务。ScheduledThreadPoolExecutor 的功能与 Timer 类似,但 Timer 对应的是单个后台线程,而 ScheduledThreadPoolExecutor 可以在构造函数中指定多个对应的后台线程数。

    1. JUC源码分析-线程池篇(三)Timer

    1. ScheduledThreadPoolExecutor 简介

    1.1 Timer 和 ScheduledThreadPoolExecutor 区别

    Timer ScheduledThreadPoolExecutor
    单线程 多线程
    单个任务执行时间影响其他任务调度 多线程,不会影响
    基于绝对时间 基于相对时间
    一旦执行任务出现异常不会捕获,其他任务得不到执行 多线程,单个任务的执行不会影响其他线程

    1.2 ScheduledThreadPoolExecutor 执行流程

    ScheduledThreadPoolExecutor 的结构和 Timer 类似,也是由 DelayedWorkQueue、ThreadPoolExecutor、ScheduledFutureTask 三部分组成。DelayedWorkQueue 是一个无界队列,所以 ThreadPoolExecutor 的 maximumPoolSize 在 ScheduledThreadPoolExecutor 中没有什么意义(设置 maximumPoolSize 的大小没有什么效果)。

    ScheduledThreadPoolExecutor 的执行主要分为两大部分。

    1)当调用 ScheduledThreadPoolExecutor#scheduleAtFixedRate() 方法或者 scheduleWithFixedDelay() 方法时,会向 ScheduledThreadPoolExecutor#DelayedWorkQueue 添加一个实现了 RunnableScheduledFutur 接口的 ScheduledFutureTask。

    2)线程池中的线程从 DelayedWorkQueue 中获取 ScheduledFutureTask,然后执行任务。

    ScheduledThreadPoolExecutor执行流程

    2. ScheduledThreadPoolExecutor 源码分析

    2.1 数据结构

    ScheduledThreadPoolExecutor类结构

    2.2 定时任务调度 schedule

    schedule、scheduleAtFixedRate、scheduleWithFixedDelay 只是将任务设置执行时间后添加到线程池队列中去了。

    ublic 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;
    }
    
    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;
    }
    

    2.3 任务执行 ScheduledFutureTask#run

    public void run() {
        boolean periodic = isPeriodic();
        if (!canRunInCurrentRunState(periodic)) // 线程池关闭时是否断续执行定时任务
            cancel(false);
        else if (!periodic)     // 只执行一次
            ScheduledFutureTask.super.run();
        else if (ScheduledFutureTask.super.runAndReset()) { // 周期性执行
            setNextRunTime();               // 下一次执行时间 
            reExecutePeriodic(outerTask);   // 重新添加到任务队列中
        }
    }
    

    参考:

    1. 《深入理解Java线程池:ScheduledThreadPoolExecutor》:https://www.jianshu.com/p/925dba9f5969

    每天用心记录一点点。内容也许不重要,但习惯很重要!

  • 相关阅读:
    ORB-SLAM(五)优化
    ORB-SLAM(四)追踪
    ORB-SLAM(三)地图初始化
    SVM(支持向量机)的一点理解
    ORB-SLAM(二)性能
    ORB-SLAM(一)简介
    支持高并发的IIS Web服务器常用设置
    微信JS SDK Demo
    C#开发微信门户及应用-使用地理位置扩展相关应用
    DropdownListFor无法正确绑定值-同名问题
  • 原文地址:https://www.cnblogs.com/binarylei/p/10963067.html
Copyright © 2020-2023  润新知