图解定时任务线程池

线程池概念


们上篇文章分析了ThreadPoolExecutor,如果要用一句话说明它的主要优势,就是线程置换。还有Executors工具类,极大的简化了研发人员工作。

用一个图重复描述下线程池概念。多生产-多消费模型。

image.png

  • 生产者将线程任务丢进线程池中,生产者就就结束了。
  • 线程池控制消费者消费元素,消费者可以是1个或者多个,取决于线程池参数corePoolSize和maxPoolSize设置。
  • 阻塞队列是用来装生产者丢进去的线程任务,如ArrayBlockingQueue,LinkedBlockingQueue,DelayedQueue等。如果生产者生产能力超过消费者消费能力,如果阻塞队列有长度限制并且超过队列长度线程池会执行饱和策略,如果队列没有长度限制,可也能出现OOM哦,因为线程任务可能把内存都撑爆了,这也是面试常考点哦!

详细概念可以翻看上一篇文章《线程池面试必考问题》。

定时任务延时原理


还记得们上面说的阻塞队列吗?定时任务线程池底层使用DelayedQueue 实现的,这种延迟队列有一个最大的特点:按时出队列,大家都考过驾照吧,科目三考试的时候都是车上坐的是4个人,假设一个人考试需要花15分钟,那么考试学员队列看起来是这样的。

image.png DelayedQueue底层需要实现Delayed接口同时需要实现getDelay方法和compareTo方法,getDelay方法用于计算出队列时间,一旦小于0就会出队列;compareTo方法用于按触发时间从小到大排序。这就是Schedule线程池任务延时原理,如果需要看案例代码,请参考文章《并发队列:PriorityBlockingQueue和DelayQueue案例使用》。

scheduleWithFixedDelay和scheduleAtFixedRate区别


image.png

由上图可知:假设线程任务:耗时1秒,定时3秒执行,scheduleWithFixedDelay其实是4秒执行一次。

  • scheduleWithFixedDelay:是以任务结束时间周期运行。
  • scheduleAtFixedRate:是以固定周期运行。

FutureTask获取返回值


在ScheduledThreadPoolExecutor中,ScheduledFutureTask是获取定时任务返回值,继承FutureTask。们看下FutureTask调用get阻塞简化流程图。

image.png

  1. 向线程池添加任务,任务被封装成ScheduledFutureTask并且实现Callable接口是为了获取任务返回值。
  2. 当客户端线程通过get方式获取线程池线程执行的返回值,客户端线程会阻塞直到线程池线程任务执行完。 在实际运用,们一般拿返回值测试多线程性能。

Timer比较


  1. Timer是单线程,而且不带返回值。ScheduledThreadPoolExecutor是多线程的,采用线程复用代替创建新的线程,并且FutureTask带返回值。
  2. Timer线程调用sche方法,如果TimerTask出异常,Timer单线程直接挂掉退出,而ScheduledThreadPoolExecutor会捕获了异常,不影响其他消费者线程。下面是代码测试。
    import java.util.Timer;
    import java.util.TimerTask;
    import java.util.concurrent.TimeUnit;
    /**
    
  3. @author :jiaolian
  4. @date :Created in 2021-02-25 13:50
  5. @description:Timer任务异常,Timer线程退出!
  6. @modified By:
  7. 公众号:叫练 */ public class TimerTaskExceptionTest { public static void main(String[] args) throws InterruptedException {
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            System.out.println("first_task");
        }
    },0,1000);
    TimeUnit.SECONDS.sleep(3);
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            System.out.println("second_task");
            int x = 5/0;
        }
    },0,1000);
    
    } }

如上代码:timer提交了first_task和second_task两个任务,3秒后,second_task执行5/0会抛出异常,此时timer线程会退出。如果换成ScheduledThreadPoolExecutor则不会影响first_task。在实际应用中,推荐用定时任务线程池中的方法去处理任务。

总结


今天们介绍了线程池中面试中几个重要的面试点,整理出来希望能对你有帮助,写的比不全,同时还有许多需要修正的地方,希望亲们加以指正和点评,喜欢的请点赞加关注哦。点关注,不迷路,叫练【公众号】 ,微信号【jiaolian123abc】边叫边练。

[] ) [](top

原文创作:叫练

原文链接:https://www.cnblogs.com/jiaolian/p/14446911.html

文章列表

更多推荐

更多
  • 九、Azure 发布管道——服务连接、模板、工件、阶段和环境 第 9.01 课:服务连接,第 9.02 课:使用模板,第 9.03 课:发布的工件,第 9.04 课:发布阶段,第 9.05 课:环境,摘要, 在前几章中,我们讨论了设置构建管道的特性和选项。构建管道允许您构建源代码并使用构建的二进制
    Apache CN

  • Azure ppl流水线-八、创建和使用 YAML 生成管道 第 8.01 课:YAML 管道入门,第 8.02 课:设置管道触发器和过滤器,第 8.03 课:在 YAML 中使用变量,第 8.04 课:管道中的作业和阶段,第 8.05 课:工作中的步骤和任务,第 8.06 课:使用模板,摘要,
    Apache CN

  • 十、Azure 发布管道——作业、部署组、变量和其他选项 第 10.01 课:代理作业,第 10.02 课:部署组作业,第 10.03 课:无代理作业,第 10.04 课:变量,第 10.05 课:其他有用的功能,摘要, 在前一章中,我们讨论了一些与发布管道相关的重要特性。描述了允许发布管理的
    Apache CN

  • Azure ppl流水线-十一、REST API、命令行和扩展开发 第 11.01 课:使用构建和发布 REST APIs,第 11.02 课:使用 Azure 管道 CLI,第 11.03 课:开发和分发扩展,摘要, 在前几章,我们讨论了 Azure DevOps 中的构建和发布管道。我们已经研究了经
    Apache CN

  • Azure ppl流水线-十二、将测试集成到管道中 第 12.01 课:使用管道运行单元测试,第 12.02 课:使用管道运行功能测试,摘要, 测试是软件交付过程中非常重要的一个方面。为了保证交付的软件项目或产品的质量,一些测试类型可以很容易地自动化,并与构建和发布管道相集成。在这一
    Apache CN

  • 五、创建构建管道——经典——变量、触发器、过滤器、选项和保留 第 5.01 课:使用变量,第 5.02 课:设置触发器和路径过滤器,第 5.03 课:格式化内部版本号,第 5.04 课:启用、禁用和暂停生成,第 5.05 课:生成和工作项,第 5.06 课:构建状态徽章,第 5.07 课:其他构建
    Apache CN

  • 六、创建构建管道——经典——排队、调试、任务组、工件和导入/导出选项 第 6.01 课:排队生成和启用调试模式以获取更多诊断信息,第 6.02 课:在 PowerShell 脚本中设置变量值,第 6.03 课:在 PowerShell 中访问秘密变量值,第 6.04 课:在构建中使用身份验证令牌,第 6.
    Apache CN

  • 四、创建构建管道——经典——源代码管理、模板、作业和任务 第 4.01 课:使用源代码管理提供程序,第 4.02 课:使用模板,第 4.03 课:使用多重职务,第 4.04 课:使用任务,摘要, 构建管道允许您编译源代码,运行单元测试,并将您的代码发布为可部署的工件。在经典的构建管道中,您可以
    Apache CN

  • Azure ppl流水线-七、使用工件 第 7.01 课:发布构建工件,第 7.02 课:将工件打包并发布为 NuGet,第 7.03 课:在构建中使用 NuGet 包,摘要, 构建的工件或输出包含二进制文件和将软件部署到目标环境所需的支持文件。根据正在构建的项目类型,以及部
    Apache CN

  • Azure ppl流水线-三、设置池、部署组和代理 第 3.01 课:设置池和权限,第 3.02 课:向池中添加代理,第 3.03 课:设置部署组,第 3.04 课:向部署组添加目标,摘要, 在前两章中,我们讨论了持续集成和交付的概念,并简要探讨了 Azure Pipelines 的概念
    Apache CN

  • 近期文章

    更多
    文章目录

      推荐作者

      更多