定时任务里面的任务多线程操作

简介: 该内容是关于Spring Boot中配置异步任务和定时任务的代码示例。首先通过`@Configuration`和`@EnableAsync`开启异步支持,然后定义线程池,如使用`ThreadPoolExecutor`并设置核心线程数、最大线程数等参数。接着,在需要异步执行的方法上添加`@Async`注解。此外,通过`@EnableScheduling`开启定时任务,并使用`@Scheduled`定义具体任务和执行周期。若需指定多个线程池,可以创建不同的`Executor` bean,并在`@Async`中指定线程池名称。

 

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import java.util.concurrent.*;
@Configuration
@EnableAsync
public class AsyncConfig2 {
    //获取cpu数,但是好像不准
    private static final int NTHREADS = Runtime.getRuntime().availableProcessors();
    private static ThreadFactory SENDE_FACTORY = new ThreadFactoryBuilder()
            .setNameFormat("send-pool-%d").build();
    
    @Bean
    public Executor taskExecutor() {
        ExecutorService sendEmailForM3MerchanthreadPool = new ThreadPoolExecutor(NTHREADS * 2, NTHREADS * 2, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1000),SEND_FACTORY );
        return sendMerchanthreadPool;
    }
}

image.gif

或者

@Configuration
@EnableAsync
public class AsyncConfig implements SchedulingConfigurer {
    /**
     * 获取cpu数
     */
    private static final int NTHREADS = Runtime.getRuntime().availableProcessors();
    /**
     * 定义线程工厂名称
     */
    private static ThreadFactory HANDLEREMINDWAY_FACTORY = new ThreadFactoryBuilder()
            .setNameFormat("handleRemindWay-pool-%d").build();
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(NTHREADS * 2, HANDLEREMINDWAY_FACTORY));
    }
}

image.gif

1、定义定时任务,添加@EnableAsync开启对异步的支持

2、在springboot启动类加上注解

@EnableScheduling

image.gif

3、在使用的地方定义

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
@EnableScheduling
public class Send {
    private final static Logger log = LoggerFactory.getLogger(Send.class);
    @Async
    @Scheduled(cron = "0/1 * * * * ?")
    public void doBiz() {
        log.info("定时任务开始 :{} " + "\r\n线程 : {}", LocalDateTime.now().toLocalTime(), Thread.currentThread().getName());
    }
}

image.gif

指定多个线程池的方式:

或者配置多个线程池

@Configuration
@EnableAsync
public class ExecutorConfig1 {
 @Bean
 public Executor executor1() {
  ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  executor.setThreadNamePrefix("test-schedule1-");
  executor.setMaxPoolSize(20);
  executor.setCorePoolSize(15);
  executor.setQueueCapacity(0);
  executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  return executor;
 }
 
 @Bean
 public Executor executor2() {
  ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  executor.setThreadNamePrefix("test-schedule2-");
  executor.setMaxPoolSize(20);
  executor.setCorePoolSize(15);
  executor.setQueueCapacity(0);
  executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  return executor;
  }
}

image.gif

使用

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
@EnableScheduling
public class Send {
    private final static Logger log = LoggerFactory.getLogger(Send.class);
    @Async("executor2")
    @Scheduled(cron = "0/1 * * * * ?")
    public void doBiz() {
        log.info("定时任务开始 :{} " + "\r\n线程 : {}", LocalDateTime.now().toLocalTime(), Thread.currentThread().getName());
    }
}

image.gif

目录
相关文章
|
2天前
|
Java 数据库 Android开发
【专栏】Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理
【4月更文挑战第27天】本文探讨了Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理。通过案例分析展示了网络请求、图像处理和数据库操作的优化实践。同时,文章指出并发编程的挑战,如性能评估、调试及兼容性问题,并强调了多线程优化对提升应用性能的重要性。开发者应持续学习和探索新的优化策略,以适应移动应用市场的竞争需求。
|
2天前
|
算法 调度 索引
什么是多任务和线程?用线程写的一个udp同步聊天器
什么是多任务和线程?用线程写的一个udp同步聊天器
31 0
|
2天前
|
数据采集 存储 Java
「多线程大杀器」Python并发编程利器:ThreadPoolExecutor,让你一次性轻松开启多个线程,秒杀大量任务!
「多线程大杀器」Python并发编程利器:ThreadPoolExecutor,让你一次性轻松开启多个线程,秒杀大量任务!
|
2天前
|
存储 算法 Java
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
90 0
|
1天前
|
消息中间件 前端开发 Java
美团面试:如何实现线程任务编排?
线程任务编排指的是对多个线程任务按照一定的逻辑顺序或条件进行组织和安排,以实现协同工作、顺序执行或并行执行的一种机制。 ## 1.线程任务编排 VS 线程通讯 有同学可能会想:那线程的任务编排是不是问的就是线程间通讯啊? 线程间通讯我知道了,它的实现方式总共有以下几种方式: 1. Object 类下的 wait()、notify() 和 notifyAll() 方法; 2. Condition 类下的 await()、signal() 和 signalAll() 方法; 3. LockSupport 类下的 park() 和 unpark() 方法。 但是,**线程通讯和线程的任务编排是
|
2天前
|
存储 安全 Java
Java多线程实战-从零手搓一个简易线程池(一)定义任务等待队列
Java多线程实战-从零手搓一个简易线程池(一)定义任务等待队列
|
2天前
|
安全 Java 调度
【C/C++ 线程池设计思路 】设计与实现支持优先级任务的C++线程池 简要介绍
【C/C++ 线程池设计思路 】设计与实现支持优先级任务的C++线程池 简要介绍
59 2
|
2天前
|
Java
多线程------Future异步任务
多线程------Future异步任务
|
2天前
|
分布式计算 安全 Java
线程状态:深入理解多任务并发编程中的精髓
线程状态:深入理解多任务并发编程中的精髓
|
2天前
|
Python
在Python中,如何使用多线程或多进程来实现任务的并行执行?
在Python中,如何使用多线程或多进程来实现任务的并行执行?
149 1