ThreadPoolTaskScheduler轻量级多线程定时任务框架

简介: 面对一些小的功能需求点,如果需要非常灵活的进行处理定时任务处理,但是又因为你的需求需要使用到页面进行定时任务配置,显然使用Spring注解定时任务,无法满足你,这时你想到了xxl-job 或者 quezy等定时任务框架,但是过于繁琐,可能成本较大。那么本文将要解决你的问题

一、ThreadPoolTaskScheduler是什么?

  • springboot中有一个bean,ThreadPoolTaskScheduler,可以很方便的对重复执行的任务进行调度管理;相比于通过java自带的周期性任务线程池
  • ScheduleThreadPoolExecutor,此bean对象支持根据cron表达式创建周期性任务。
  • 当然,ThreadPoolTaskScheduler其实底层使用也是java自带的线程池。

二、上干货

1.ThreadPoolTaskScheduler常用的api介绍

ThreadPoolTaskScheduler 内部方法非常丰富,本文实现的是一种corn表达式,周期执行

  • schedule(Runnable task, Trigger trigger) corn表达式,周期执行
  • schedule(Runnable task, Date startTime) 定时执行
  • scheduleAtFixedRate(Runnable task, Date startTime, long period)
    定时周期间隔时间执行。间隔时间单位 TimeUnit.MILLISECONDS
  • scheduleAtFixedRate(Runnable task, long period) 间隔时间执行。单位毫秒

2.springboot中创建配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
public class TaskConfig {

    //配置定时任务线程池-自定义名称避免冲突
    @Bean(name = "myThreadPoolTaskScheduler")
    public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
        ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();
        executor.setPoolSize(2);
        executor.setThreadNamePrefix("task-");
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        return executor;
    }

}

3.实现Runnable的业务处理类

代码如下(示例):

@Slf4j
public class RunSameThing implements Runnable{

    @Override
    public void run() {
        log.info("===我执行了===");
    }
}

4.业务处理服务service

import java.util.concurrent.ScheduledFuture;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class CommonTask {

    @Resource(name = "myThreadPoolTaskScheduler")
    private ThreadPoolTaskScheduler taskScheduler;

    private ScheduledFuture future;
    //开启任务
    public void startTask(){
        //每次调用前,可执行一次关闭之前的
        stop();
        //每秒执行-corn 表达式可传参形式
        String cron = "0/1 * * * * ?";
        //RunSameThing 为执行的业务逻辑
        future = taskScheduler.schedule(new RunSameThing(), new CronTrigger(cron));
    }
    //关闭任务
    public void stop() {
        if (future != null) {
            log.info("我关闭了");
            future.cancel(true);
        }
    }
}

5.调用controller

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/task")
public class TestTaskController {

    @Autowired
    private CommonTask commonTask;

    @RequestMapping("start")
    public void startTask(){
        commonTask.startTask();
    }

    @RequestMapping("end")
    public void endTask(){
        commonTask.stop();
    }

}

6.让我们看看运行结果


task-1] com.easy.wheel.scheduler.RunSameThing    : ===我执行了===
task-2] com.easy.wheel.scheduler.RunSameThing    : ===我执行了===
task-2] com.easy.wheel.scheduler.RunSameThing    : ===我执行了===
task-1] com.easy.wheel.scheduler.RunSameThing    : ===我执行了===
task-1] com.easy.wheel.scheduler.RunSameThing    : ===我执行了===
task-2] com.easy.wheel.scheduler.RunSameThing    : ===我执行了===
task-1] com.easy.wheel.scheduler.RunSameThing    : ===我执行了===
task-1] com.easy.wheel.scheduler.RunSameThing    : ===我执行了===
task-1] com.easy.wheel.scheduler.RunSameThing    : ===我执行了===
task-2] com.easy.wheel.scheduler.RunSameThing    : ===我执行了===
[nio-8080-exec-2] com.easy.wheel.scheduler.CommonTask      : 我关闭了

线程池配置的两个线程,可以看到task-1 和 task-2 交替支持,达到了我们想要的效果,关闭也能正常进行关闭,nice。这个轮子搞定了,下次写代码直接复制。巴适


总结

生活不能止步不前,为了更多的时间陪陪家人,轮子用起来啊,亲

目录
相关文章
|
6月前
|
Java 调度 开发者
JDK 21中的虚拟线程:轻量级并发的新篇章
本文深入探讨了JDK 21中引入的虚拟线程(Virtual Threads)概念,分析了其背后的设计哲学,以及与传统线程模型的区别。文章还将讨论虚拟线程如何简化并发编程,提高资源利用率,并展示了一些使用虚拟线程进行开发的示例。
1071 4
|
6月前
|
人工智能 JSON 前端开发
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
|
5月前
|
Java
java线程之分支合并框架
java线程之分支合并框架
|
22天前
|
安全 Go 调度
goroutine:轻量级线程
【10月更文挑战第15天】
22 3
|
6月前
|
安全 Java Spring
Spring框架中的单例Bean是线程安全的吗?
Spring框架中的单例Bean是线程安全的吗?
82 1
|
1月前
|
Java API
【多线程】乐观/悲观锁、重量级/轻量级锁、挂起等待/自旋锁、公平/非公锁、可重入/不可重入锁、读写锁
【多线程】乐观/悲观锁、重量级/轻量级锁、挂起等待/自旋锁、公平/非公锁、可重入/不可重入锁、读写锁
32 0
|
3月前
|
Java 数据库连接 微服务
揭秘微服务架构下的数据魔方:Hibernate如何玩转分布式持久化,实现秒级响应的秘密武器?
【8月更文挑战第31天】微服务架构通过将系统拆分成独立服务,提升了可维护性和扩展性,但也带来了数据一致性和事务管理等挑战。Hibernate 作为强大的 ORM 工具,在微服务中发挥关键作用,通过二级缓存和分布式事务支持,简化了对象关系映射,并提供了有效的持久化策略。其二级缓存机制减少数据库访问,提升性能;支持 JTA 保证跨服务事务一致性;乐观锁机制解决并发数据冲突。合理配置 Hibernate 可助力构建高效稳定的分布式系统。
66 0
|
3月前
|
程序员 调度 C++
解锁Ruby并发编程新境界!Fiber与线程:轻量级VS重量级,你选哪一派引领未来?
【8月更文挑战第31天】Ruby提供了多种并发编程方案,其中Fiber与线程是关键机制。Fiber是自1.9版起引入的轻量级并发模型,无需独立堆栈和上下文切换,由程序员控制调度。线程则为操作系统级别,具备独立堆栈和上下文,能利用多核处理器并行执行。通过示例代码展示了Fiber和线程的应用场景,如任务调度和多URL数据下载,帮助开发者根据需求选择合适的并发模型,提升程序性能与响应速度。
48 0
|
4月前
|
设计模式 存储 安全
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
62 1
|
4月前
|
设计模式 存储 缓存
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
55 0