首页 > 其他分享 >定时任务 & 定时线程池

定时任务 & 定时线程池

时间:2022-11-12 05:22:20浏览次数:45  
标签:run 任务 线程 time DelayQueue 定时 执行

定时线程池

使用场景:

1. 分布式锁 - redis

2. springCloud - 服务注册与发现中心

ScheduledThreadPoolExecutor

它用来处理延时任务或定时任务。

 

 

 

它接收SchduledFutureTask类型的任务,是线程池调度任务的最小单位,有三种提交任务的方式:

  1. schedule
  2. scheduledAtFixedRate
  3. scheduledWithFixedDelay

它采用DelayQueue存储等待的任务

  1. DelayQueue内部封装了一个PriorityQueue,它会根据time的先后时间排序,若time相同则根据sequenceNumber排序;
  2. DelayQueue也是一个无界队列;

任务提交上来后,会将任务封装为一个ScheduledFutureTask

SchduledFutureTask接收的参数(成员变量):   1. private long time:任务开始的时间   2. private final long sequenceNumber;:任务的序号   3. private final long period:任务执行的时间间隔  工作线程的执行过程:   工作线程会从DelayQueue取已经到期的任务去执行; 执行结束后重新设置任务的到期时间,再次放回DelayQueue。 ScheduledThreadPoolExecutor会把待执行的任务放到工作队列DelayQueue中, DelayQueue封装了一个PriorityQueue,PriorityQueue会对队列中的ScheduledFutureTask进行排序,具体的排序算法实现如下:  1. 首先按照time排序,time小的排在前面,time大的排在后面; 2. 如果time相同,按照sequenceNumber排序,sequenceNumber小的排在前面,sequenceNumber大的排在后面,换句话说,如果两个task的执行时间相同, 优先执行先提交的task。    SchduledFutureTask之run方法实现 run方法是调度task的核心,task的执行实际上是run方法的执行:
1 public void run() {

2  boolean periodic = isPeriodic();

3 //如果当前线程池已经不支持执行任务,则取消

4  if (!canRunInCurrentRunState(periodic))

5  cancel(false);

6 //如果不需要周期性执行,则直接执行run方法然后结束

7  else if (!periodic)

8  ScheduledFutureTask.super.run();

9 //如果需要周期执行,则在执行完任务以后,设置下一次执行时间

10  else if (ScheduledFutureTask.super.runAndReset()) {

11  // 计算下次执行该任务的时间

12  setNextRunTime();

13  //重复执行任务

14  reExecutePeriodic(outerTask);

15  }

16 }

1. 如果当前线程池运行状态不可以执行任务,取消该任务,然后直接返回,否则执行 步骤2;

2. 如果不是周期性任务,调用FutureTask中的run方法执行,会设置执行结果,然后 直接返回,否则执行步骤3;

3. 如果是周期性任务,调用FutureTask中的runAndReset方法执行,不会设置执行 结果,然后直接返回,否则执行步骤4和步骤5;

4. 计算下次执行该任务的具体时间;

5. 重复执行任务。 

DelayedWorkQueue 

ScheduledThreadPoolExecutor之所以要自己实现阻塞的工作队列,是因为 ScheduledThreadPoolExecutor要求的工作队列有些特殊。

ScheduledThreadPoolExecutor之所以要自己实现阻塞的工作队列,是因为 ScheduledThreadPoolExecutor要求的工作队列有些特殊。 DelayedWorkQueue是一个基于堆的数据结构,类似于DelayQueue和 PriorityQueue。在执行定时任务的时候,每个任务的执行时间都不同,所以 DelayedWorkQueue的工作就是按照执行时间的升序来排列,执行时间距离当前时间越近 的任务在队列的前面(注意:这里的顺序并不是绝对的,堆中的排序只保证了子节点的下次 执行时间要比父节点的下次执行时间要大,而叶子节点之间并不一定是顺序的)。

heap -》堆结构

  1. 最小根堆

  2. 最大根堆

 存储数据结构是一个数组。

End!

标签:run,任务,线程,time,DelayQueue,定时,执行
From: https://www.cnblogs.com/zhf123/p/16882626.html

相关文章

  • JAVA---创建线程的4种方式
    1.创建线程的4种方式方式一:继承Thread,缺点,java是单继承,如果继承了Thread就不能继承其他类  方式二:实现runnable()接口,通常不直接在类上实现runnable接口,与类的耦......
  • Java静态代理设计模式模式(多线程Runnable)
    静态代理设计模式,就是代理对象来帮你忙前忙后,你负责出席一下就好了。需要:1.实现相同的接口2.真实角色3.代理角色,里面有一个成员是接口对象(实际上是真实角色----接口实......
  • 超算第二次考核任务
    后缀表达式/* 第一版中缀表达式便后缀表达式*/#include<iostream>#include<bits/stdc++.h>#include<string.h>#defineMAX1001usingnamespacestd;enumfuhao......
  • Linux网络通信(线程池和线程池版本的服务器代码)
    线程池介绍线程池:一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在......
  • JAVA 六种常见线程池
    在我们日常业务开发中,如果遇到使用线程池的场景时,会先去思考一下这种场景需要使用到怎样的线程池,去避免线程资源滥用。这个时候选择困难症就来了,不过不用担心,Java其实早......
  • Multi-task Learning 理论(多任务学习)
    一.多任务学习理论1.1多任务学习的定义如果有\(n\)个任务(传统的深度学习方法旨在使用一种特定模型仅解决一项任务),而这\(n\)个任务或它们的一个子集彼此相关但不完全相......
  • Linux 定时任务crontab监控重启java服务脚本
    linux服务器下,利用Linux定时器和简单监控脚本,监控自动重启java服务。注意:脚本最好在Linux系统中用touch建立.sh文件,并用shmod+x+‘脚本文件名’,在window下编辑有可能会......
  • 【Java】多线程 语法 使用
    在java中使用多线程有三种方式。1.继承Thread类;2.实现Runnable接口;3.匿名内部类;第一种一般不用,因为java只允许单继承,万一这个业务类有父类就无法继承了。第二种如下:publicc......
  • 【转】多线程下的fork及写时复制导致的性能问题
    名词解释PHPvsHHVM:PHP指的是​​php.net(Zend)​​​实现的PHP,而HHVM指的是​​Facebook开源的PHP实现​​。PHP-FPM:(PHPFastcgiProcessManager)一个PHPSapi实现......
  • 线程池
    线程池线程池介绍背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可......