jdk自带定时调度类Timer和定时任务类TimerTask及spring的定时任务

2024-05-10 23:32

本文主要是介绍jdk自带定时调度类Timer和定时任务类TimerTask及spring的定时任务,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

java定时器Timer原理:https://www.cnblogs.com/luckygxf/p/7078662.html

 

TBschedule分布式定时任务调度框架

传统的调度框架spring task、quartz也是可以进行集群调度作业的,一个节点挂了可以将任务漂移给其他节点执行从而避免单点故障,但是不支持分布式作业,一旦达到单机处理极限也会存在问题。

jdk自带定时调度类Timer和定时任务类TimerTask

Timer:

构造方法(不论哪个构造函数最后都会创建新线程TimerThread并调用含有启动该线程start()方法的构造函数):

也就是说创建一个Timer对象就相当于启动了一个TimerThread线程¥1

 public Timer()
  {
    this("Timer-" + serialNumber());
  }
  
  public Timer(boolean paramBoolean)
  {
    this("Timer-" + serialNumber(), paramBoolean);
  }
  
  public Timer(String paramString)
  {
    this.thread.setName(paramString);
    this.thread.start();
  }
  
  public Timer(String paramString, boolean paramBoolean)
  {
    this.thread.setName(paramString);
    this.thread.setDaemon(paramBoolean);//是否设为守护线程/后台(后台程序的后台)线程,在后台运行直到进程结束。
    this.thread.start();

  }

 

线程启动后执行的run方法:

public void run()
  {
    try
    {
      mainLoop();
      synchronized (this.queue)
      {
        this.newTasksMayBeScheduled = false;
        this.queue.clear();
      }
    }
    finally
    {
      synchronized (this.queue)
      {
        this.newTasksMayBeScheduled = false;
        this.queue.clear();
      }
    }
  }

  private void mainLoop()
  {
    try
    {
      for (;;) // 无线循环直到遇到break退出
      {
        TimerTask localTimerTask;
        int i;
        synchronized (this.queue)
        {
          if ((this.queue.isEmpty()) && (this.newTasksMayBeScheduled))
          {
            this.queue.wait(); continue;
          }
          if (this.queue.isEmpty()) {
            break;
          }
          localTimerTask = this.queue.getMin();
          long l1;
          long l2;
          synchronized (localTimerTask.lock)
          {
            if (localTimerTask.state == 3)
            {
              this.queue.removeMin();
              continue;
            }
            l1 = System.currentTimeMillis();
            l2 = localTimerTask.nextExecutionTime;
            if ((i = l2 <= l1 ? 1 : 0) != 0) {
              if (localTimerTask.period == 0L)
              {
                this.queue.removeMin();
                localTimerTask.state = 2;
              }
              else
              {
                this.queue.rescheduleMin(localTimerTask.period < 0L ? l1 - localTimerTask.period : l2 + localTimerTask.period);
              }
            }
          }
          if (i == 0) {
            this.queue.wait(l2 - l1);
          }
        }
        if (i != 0) {
          localTimerTask.run();
        }
      }
    }
    catch (InterruptedException localInterruptedException) {}
  }

调度方法:

  public void schedule(TimerTask paramTimerTask, long paramLong)
  {paramLong后调度一次
    if (paramLong < 0L) {
      throw new IllegalArgumentException("Negative delay.");
    }
    sched(paramTimerTask, System.currentTimeMillis() + paramLong, 0L);
  }
  
  public void schedule(TimerTask paramTimerTask, Date paramDate)
  {在指定时间paramDate处调度一次
    sched(paramTimerTask, paramDate.getTime(), 0L);
  }
  
  public void schedule(TimerTask paramTimerTask, long paramLong1, long paramLong2)
  {paramLong1后开始调度,完成后至少等待paramLong2这么久再次调度
    if (paramLong1 < 0L) {
      throw new IllegalArgumentException("Negative delay.");
    }
    if (paramLong2 <= 0L) {
      throw new IllegalArgumentException("Non-positive period.");
    }
    sched(paramTimerTask, System.currentTimeMillis() + paramLong1, -paramLong2);
  }
  
  public void schedule(TimerTask paramTimerTask, Date paramDate, long paramLong)
  {在paramDate处开始调度,完成后至少等待paramLong这么久再次调度
    if (paramLong <= 0L) {
      throw new IllegalArgumentException("Non-positive period.");
    }
    sched(paramTimerTask, paramDate.getTime(), -paramLong);
  }
  
  public void scheduleAtFixedRate(TimerTask paramTimerTask, long paramLong1, long paramLong2)
  {paramLong1后开始调度,若调度被推迟完成,完成后按第一次调度计划时间+paramLong2来进行下一次调度
    if (paramLong1 < 0L) {
      throw new IllegalArgumentException("Negative delay.");
    }
    if (paramLong2 <= 0L) {
      throw new IllegalArgumentException("Non-positive period.");
    }
    sched(paramTimerTask, System.currentTimeMillis() + paramLong1, paramLong2);
  }
  
  public void scheduleAtFixedRate(TimerTask paramTimerTask, Date paramDate, long paramLong)
  {在paramDate处开始调度,若调度被推迟完成,完成后按第一次调度计划时间+paramLong2来进行下一次调度
    if (paramLong <= 0L) {
      throw new IllegalArgumentException("Non-positive period.");
    }
    sched(paramTimerTask, paramDate.getTime(), paramLong);
  }

上面所有方法最后调sched(paramTimerTask, paramDate.getTime(), paramLong);方法时传入的都是开始执行的时间。

private void sched(TimerTask paramTimerTask, long paramLong1, long paramLong2)
  {
    if (paramLong1 < 0L) {
      throw new IllegalArgumentException("Illegal execution time.");
    }
    if (Math.abs(paramLong2) > 4611686018427387903L) {
      paramLong2 >>= 1; 即paramLong2=paramLong2 >>1(基于二进制向右移一位)
    }
    synchronized (this.queue)
    {
      if (!this.thread.newTasksMayBeScheduled) {
        throw new IllegalStateException("Timer already cancelled.");
      }
      synchronized (paramTimerTask.lock)
      {
        if (paramTimerTask.state != 0) {
          throw new IllegalStateException("Task already scheduled or cancelled");
        }
        paramTimerTask.nextExecutionTime = paramLong1;
        paramTimerTask.period = paramLong2;
        paramTimerTask.state = 1;
      }
      this.queue.add(paramTimerTask);
      if (this.queue.getMin() == paramTimerTask) {
        this.queue.notify();
      }
    }

  }

 

https://www.cnblogs.com/dolphin0520/p/3938991.html

 

 

 

 

 

 

 

 

 

http://code.taobao.org/p/tbschedule/wiki/index/

 

TBschedule业务接口说明

包含三个业务接口,:
1、IScheduleTaskDeal 调度器对外的基础接口,是一个基类,并不能被直接使用
2、IScheduleTaskDealSingle 单任务处理的接口,继承 IScheduleTaskDeal
3、IScheduleTaskDealMulti 可批处理的任务接口,继承 IScheduleTaskDeal

IScheduleTaskDeal 调度器对外的基础接口

public interface IScheduleTaskDeal<T> {
/*** 根据条件,查询当前调度服务器可处理的任务	* @param taskParameter 任务的自定义参数* @param ownSign 当前环境名称* @param taskQueueNum 当前任务类型的任务队列数量* @param taskQueueList 当前调度服务器,分配到的可处理队列* @param eachFetchDataNum 每次获取数据的数量* @return* @throws Exception*/
public List<T> selectTasks(String taskParameter,String ownSign,int taskQueueNum,List<TaskItemDefine> taskItemList,int eachFetchDataNum) throws Exception;/*** 获取任务的比较器,只有在NotSleep模式下需要用到* @return*/
public Comparator<T> getComparator();
}                                    

IScheduleTaskDealSingle 单任务处理的接口

public interface IScheduleTaskDealSingle<T> extends IScheduleTaskDeal<T> {/*** 执行单个任务* @param task Object* @param ownSign 当前环境名称* @throws Exception*/public boolean execute(T task,String ownSign) throws Exception;}                                       

IScheduleTaskDealMulti 可批处理的任务接口

public interface IScheduleTaskDealMulti<T>  extends IScheduleTaskDeal<T> {/*** 	执行给定的任务数组。因为泛型不支持new 数组,只能传递OBJECT[]* @param tasks 任务数组* @param ownSign 当前环境名称* @return* @throws Exception*/public boolean execute(Object[] tasks,String ownSign) throws Exception;
}     

 

 

Spring Quartz 和 Spring Task对比

https://blog.csdn.net/wmy_0707/article/details/79495496

 

spring定时任务:

1.加载不能用懒加载,若其他bean需要懒加载,可在spring定时类上单独配@Lazy(false)

2.定时类即可用@Component来被扫描,也可用@Service("类名")来扫描

 

这篇关于jdk自带定时调度类Timer和定时任务类TimerTask及spring的定时任务的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/977865

相关文章

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

javacv依赖太大导致jar包也大的解决办法

《javacv依赖太大导致jar包也大的解决办法》随着项目的复杂度和依赖关系的增加,打包后的JAR包可能会变得很大,:本文主要介绍javacv依赖太大导致jar包也大的解决办法,文中通过代码介绍的... 目录前言1.检查依赖2.更改依赖3.检查副依赖总结 前言最近在写项目时,用到了Javacv里的获取视频

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分