任务执行和调度----Spring线程池/Quartz

news2024/11/20 8:41:05

定时任务

在服务器中可能会有定时任务,但是不知道分布式系统下次会访问哪一个服务器,所以服务器中的任务就是相同的,这样会导致浪费。使用Quartz可以解决这个问题。
在这里插入图片描述

JDK线程池

@RunWith(SpringRunner.class)
@SpringBootTest	
@ContextConfiguration(classes = MyCommunityApplication.class)
public class ThreadPoolTest {

    private Logger logger = LoggerFactory.getLogger(ThreadPoolTest.class);

	// JDK's normal thread-pool
    private ExecutorService executorService = Executors.newFixedThreadPool(5);

    // JDK's thread pool that periodically executes tasks
    private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);

    private void sleep(long m){
        try{
            Thread.sleep(m);
        } catch(InterruptedException e){
            e.printStackTrace();
        }
    }

    @Test
    public void testExecutorService() {
        Runnable task = new Runnable() {
            @Override
            public void run() {
                logger.info("hello executor service");
            }
        };

        for(int i = 0; i < 10; i++) {
            executorService.submit(task);
        }

        sleep(10000);
    }

    @Test
    public void testScheduleExecutorService(){
        Runnable task = new Runnable() {
            @Override
            public void run() {
                logger.info("hello executor service");
            }
        };

		// 初始时间间隔为10000ms,任务间隔为1000ms
        for(int i = 0; i < 10; i++) {
            scheduledExecutorService.scheduleAtFixedRate(task, 10000, 1000, TimeUnit.MILLISECONDS);
        }

        sleep(30000);
    }
}

Spring线程池

配置application.properties

# Spring thread pool
# TaskExecutionProperties
spring.task.execution.pool.core-size=5
spring.task.execution.pool.max-size=15
spring.task.execution.pool.queue-capacity=100
# TaskScheduleProperties
spring.task.scheduling.pool.size=5

Spring线程池默认不开启定时线程池,需要新建配置类手动开启:

@Configuration
@EnableScheduling	// 允许定时线程池
@EnableAsync		// 允许多线程执行
public class ThreadPoolConfig {

}

基于注入

测试方法:

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = MyCommunityApplication.class)
public class ThreadPoolTest {

    private Logger logger = LoggerFactory.getLogger(ThreadPoolTest.class);

    // Spring's normal thread pool
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    // Spring's thread pool that periodically executes tasks
    // 如果配置类不加@EnableScheduling会报错
    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;

    private void sleep(long m){
        try{
            Thread.sleep(m);
        } catch(InterruptedException e){
            e.printStackTrace();
        }
    }

    @Test
    public void testThreadPoolTaskExecutor(){
        Runnable task = new Runnable() {
            @Override
            public void run() {
                logger.info("hello spring thread pool");
            }
        };

        for(int i = 0; i < 10; i++){
            taskExecutor.submit(task);
        }

        sleep(10000);
    }

    @Test
    public void testThreadPoolTaskScheduler(){
        Runnable task = new Runnable() {
            @Override
            public void run() {
                logger.info("hello spring thread pool");
            }
        };

        Date start = new Date(System.currentTimeMillis() + 10000);
//        for(int i = 0; i < 10; i++){
            taskScheduler.scheduleAtFixedRate(task, start, 1000);
//        }

        sleep(10000);
    }
}

基于注解

@Service
public class AlphaService {
	
	// 此前已经在配置类上允许了异步及定时
	// @EnableScheduling	// 允许定时线程池
	// @EnableAsync		// 允许异步执行

	// 加上这个注解说明是异步的
    @Async
    public void execute1(){
        logger.info("hello");
    }

	// 加上这个注解说明是定时任务
	// 第一次延迟10s,之后每次间隔1s
	// @Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影响。
    @Scheduled(initialDelay = 10000, fixedRate = 1000)
    public void execute2(){
        logger.info("hello2");
    }
}
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = MyCommunityApplication.class)
public class ThreadPoolTest {

    private Logger logger = LoggerFactory.getLogger(ThreadPoolTest.class);

    // Spring's normal thread pool
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    // Spring's thread pool that periodically executes tasks
    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;

    @Autowired
    private AlphaService alphaService;

    @Test
    public void testThreadPoolTaskExecutorSimple(){
        for(int i=0; i< 10; ++ i){
            alphaService.execute1();
        }
        sleep(10000);
    }

    @Test
    public void testThreadPoolTaskExecutorSimple2(){
    	// 此处不需要调用alphaService.execute2方法
    	// 因为有Scheduled注解的方法在程序开始时会自动执行
//      alphaService.execute2();
        sleep(30000);
    }
}

分布式定时任务

新建任务

参考链接
在这里插入图片描述
引入依赖包

		<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-quartz -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-quartz</artifactId>
<!--			<version>3.1.2</version>-->
		</dependency>

配置Quartz

# QuartzProperties
spring.quartz.job-store-type=jdbc
spring.quartz.scheduler-name=communityScheduler
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
#spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
spring.quartz.properties.org.quartz.jobStore.class=org.springframework.scheduling.quartz.LocalDataSourceJobStore
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.properties.org.quartz.jobStore.isClustered=true
spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
spring.quartz.properties.org.quartz.threadPool.threadCount=5

定义Job类:

public class AlphaJob implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println(Thread.currentThread().getName() + ":execute a quartz job");
    }
}

定义Quartz的配置类,该配置类只执行一次便被存入数据库的几个表中在这里插入图片描述

// this configuration just for the first execution, and then the configuration will be saved in the database
@Configuration
public class QuartzConfig {

    // `FactoryBean` simplify the instantiation process of `Bean`
    // 1.The instantiation process of `Bean` is encapsulated through `FactoryBean`
    // 2.Assemble `FactoryBean` into `Spring`'s container
    // 3.Inject `FactoryBean` into the other beans
    // 4.This bean can acquire the object instance of the bean managed by the `FactoryBean`

    // inject `JobDetailFactoryBean` into this class
    // config `JobDetail`
    @Bean
    public JobDetailFactoryBean alphaJobDetail() {
        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
        factoryBean.setJobClass(AlphaJob.class);
        factoryBean.setName("alphaJob");
        factoryBean.setGroup("alphaGroup");
        // this task will be stored permanently although there are no triggers existing
        factoryBean.setDurability(true);
        // this task can be recovered after meeting some faults
        factoryBean.setRequestsRecovery(true);

        return factoryBean;
    }

    // the `JobDetail` used is the object instance in `JobDetailFactoryBean`
    // config `Trigger(SimpleTriggerFactoryBean, CronTriggerFactoryBean)`
    @Bean
    public SimpleTriggerFactoryBean alphaTrigger(JobDetail alphaJobDetail) {
        SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
        factoryBean.setJobDetail(alphaJobDetail);
        factoryBean.setName("alphaTrigger");
        factoryBean.setGroup("alphaGroup");
        // the interval of the trigger
        factoryBean.setRepeatInterval(3000);
        // use an object to store the status of the job, `JobDataMap()` is the default object
        factoryBean.setJobDataMap(new JobDataMap());

        return factoryBean;
    }
}

启动程序后,Job自动执行,可以看到任务相关的信息已经自动加入到了表中:
在这里插入图片描述

删除任务

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = MyCommunityApplication.class)
public class QuartzTest {

    @Autowired
    private Scheduler scheduler;

    @Test
    public void testDeleteJob(){
        try {
            boolean result = scheduler.deleteJobs(Collections.singletonList(new JobKey("alphaJob", "alphaGroup")));
            System.out.println(result);
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }
}

可以看到,数据库中已经没有了关于任务的记录
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/945722.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis的五大数据类型的数据结构

概述 Redis底层有六种数据类型包括&#xff1a;简单动态字符串、双向链表、压缩列表、哈希表、跳表和整数数组。这六种数据结构五大数据类型关系如下&#xff1a; String&#xff1a;简单动态字符串List&#xff1a;双向链表、压缩列表Hash&#xff1a;压缩列表、哈希表Sorted…

指针(个人学习笔记黑马学习)

1、指针的定义和使用 #include <iostream> using namespace std;int main() {int a 10;int* p;p &a;cout << "a的地址为&#xff1a;" << &a << endl;cout << "a的地址为&#xff1a;" << p << endl;…

CPU和GPU的区别

介绍什么是GPU, 那就要从CPU和GPU的比较不同中能更好更快的学习到什么是GPU CPU和GPU的总体区别 CPU&#xff1a; 叫做中央处理器&#xff08;central processing unit&#xff09; 可以形象的理解为有25%的ALU(运算单元)、有25%的Control(控制单元)、50%的Cache(缓存单元)…

“短视频类”App个人信息收集情况测试报告

近期&#xff0c;中国网络空间安全协会对“短视频类”公众大量使用的部分App收集个人信息情况进行了测试。测试情况及结果如下&#xff1a; 一、测试对象 本次测试选取了19家应用商店⁽⁾累计下载量达到1亿次的“短视频类”App&#xff0c;共计6款&#xff0c;其基本情况如表…

StarRocks 在金融科技行业的存算分离应用实践

小编导读&#xff1a; 自从 2023 年 4 月正式推出 3.0 版本的存算分离功能以来&#xff0c;目前已有包含芒果TV、聚水潭、网易邮箱、浪潮、天道金科等数十家用户完成测试&#xff0c;多家用户也已开始逐步将其应用于实际业务中。目前&#xff0c;StarRocks 存算分离上线的场景…

【少年的救赎——放牛班的春天】

风中飞舞的风筝&#xff0c;请你别停下 池塘之底 这是马修在池塘之底写下的日记 他所有的故事&#xff0c;还有“我们”的 1949年一月十五日&#xff0c;在经历了所有领域的挫折后&#xff0c;马修来到了人生低谷期&#xff0c;“池塘之底”像专为他挑选的一般。那是在一个…

19 NAT穿透|python高级

文章目录 网络通信过程NAT穿透 python高级GIL锁深拷贝与浅拷贝私有化import导入模块工厂模式多继承以及 MRO 顺序烧脑题property属性property装饰器property类属性 魔法属性\_\_doc\_\_\_\_module\_\_ 和 \_\_class\_\_\_\_init\_\_\_\_del\_\_\_\_call\_\_\_\_dict\_\_\_\_str…

Gin 框架入门实战系列(一)

GIN介绍 Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点 对于golang而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错 借助框架开发,不仅可以省去很多常用的封装带来的时间,…

8.28~~和学长的谈话

对于大二&#xff0c;我还想问问学长有什么建议&#xff1f; 熟练掌握一到两门开发语言&#xff0c;选好专业的重点学习方向&#xff0c;开始全面了解工程实践方面&#xff0c;10个以上工程开发&#xff0c;可自行规划二年级&#xff0c;着重加强基础技能的学习和提升&#xf…

JMeter性能测试基本过程及示例

jmeter 为性能测试提供了一下特色&#xff1a; jmeter 可以对测试静态资源&#xff08;例如 js、html 等&#xff09;以及动态资源&#xff08;例如 php、jsp、ajax 等等&#xff09;进行性能测试 jmeter 可以挖掘出系统最大能处理的并发用户数 jmeter 提供了一系列各种形式的…

【100天精通python】Day47:python网络编程_Web编程基础

目录 1 网络编程与web编程 1.1 网络编程 1.2 web编程 2 Web开发概述 3 Web开发基础 3.1 HTTP协议 3.2 Web服务器 3.3 前端基础 3.4 静态服务器 3.5 前后端交互的基本原理 4 WSGI接口 4.1 CGI 简介 4.2 WSGI 简介 4.3 定义 WSGI 接口 4.4 运行 WSGI 服务 4.5…

vue3:使用:图片生成二维码并复制

实现在 vue3 中根据 url 生成一个二维码码&#xff0c;且可以复制。 注&#xff09;复制功能 navigator.clipboard.write 只能在安全的localhost 这种安全网络下使用。https中需要添加安全证书&#xff0c;且在域名&#xff08;例&#xff1a;https://www.baidu.com&#xff0…

c#多线程—基础概念到“双色球”项目实现(附知识点目录、代码、视频)

总结&#xff1a;视频中对于多线程讲的非常透彻&#xff0c;从线程基础概念—>.net不同版本出现的线程方法—>多线程常出现问题—>双色球项目实践&#xff0c;每个知识点都有代码实操&#xff0c;受益匪浅。附上学习笔记和实操代码。 视频 目录 一、线程、进程概念及优…

新建Spring Boot项目

使用IDEA 来创建: 文件-新建-项目 填写项目元数据 选择依赖项 此处可以先选 web-spring web 关于这些依赖项&#xff0c;更多可参考&#xff1a; IDEA创建Spring boot项目时各依赖的说明&#xff08;Developer Tools篇&#xff09;[1] 项目结构介绍 展开项目&#xff0c;此时…

redis应用 2:延时队列

我们平时习惯于使用 Rabbitmq 和 Kafka 作为消息队列中间件&#xff0c;来给应用程序之间增加异步消息传递功能。这两个中间件都是专业的消息队列中间件&#xff0c;特性之多超出了大多数人的理解能力。 使用过 Rabbitmq 的同学知道它使用起来有多复杂&#xff0c;发消息之前要…

socket的TCP和UDP样例

【70天稳扎稳打学完JavaEE初阶】 TCP和UDP的区别及相关的不同应用 UDP实现回显功能一、UdpEchoServer服务器二、UdpEchoClient 客户端写一个 翻译服务器&#xff08;继承服务器&#xff09; UDP示例二&#xff1a;展示服务器本地某个目录的下一级子文件列表服务UDP服务器UDP客户…

什么是ChatGPT水印,ChatGPT生成的内容如何不被检测出来,原理什么?

太长不看版 1. 什么是ChatGPT水印&#xff1f; ChatGPT水印是AI以伪随机方式生成的独特tokens序列。该序列用来作为水印&#xff0c;以区分AI生成内容和人类原创内容。 2. 如何规避ChatGPT水印&#xff1f; 一种规避方法是使用其他AI模型改写ChatGPT生成的文本。这会破坏水…

Nat. Mach. Intell 2020 | drugVQA+:准VAQ系统预测药物-蛋白质相互作用

论文标题&#xff1a;Predicting drug–protein interaction using quasi-visual question answering system 论文地址&#xff1a;Predicting drug–protein interaction using quasi-visual question answering system | Nature Machine Intelligence 代码&#xff1a;GitH…

继承AndroidView Model的错误

ViewModelProvider(this)[RegisterViewModel::class.java] 一行简单的代码&#xff0c;总是报这个错误 Caused by: java.lang.NoSuchMethodException: com.xinfa.registerlogin.viewmodel.LoginViewModel. [class android.app.Application] 经过一下午的思索&#xff0c;终于找…

科普:什么是DNS劫持?

DNS劫持又叫做域名劫持&#xff0c;指攻击者利用其他攻击手段&#xff0c;篡改了某个域名的解析结果&#xff0c;使得指向该域名的IP变成了另一个IP&#xff0c;导致对相应网址的访问被劫持到另一个不可达的或者假冒的网址&#xff0c;从而实现非法窃取用户信息或者破坏正常网络…