0

0

Springboot自带线程池怎么实现

王林

王林

发布时间:2023-06-28 16:33:05

|

930人浏览过

|

来源于亿速云

转载

一: ThreadPoolTaskExecuto

1 threadpooltaskexecutor线程池:

ThreadPoolTaskExecutor是Spring基于java本身的线程池ThreadPoolExecutor做的二次封装,主要目的还是为了更加方便的在spring框架体系中使用线程池, 是Spring中默认的线程池

2 使用ThreadPoolTaskExecutor注入bean到ioc中
  配置文件形式,Spring会自动配置

## 默认线程池配置,ThreadPoolTaskExecutor 
# 核心线程数
spring.task.execution.pool.core-size=8  
# 最大线程数
spring.task.execution.pool.max-size=16
# 空闲线程存活时间
spring.task.execution.pool.keep-alive=60s
# 是否允许核心线程超时
spring.task.execution.pool.allow-core-thread-timeout=true
# 线程队列数量
spring.task.execution.pool.queue-capacity=100
# 线程关闭等待
spring.task.execution.shutdown.await-termination=false
spring.task.execution.shutdown.await-termination-period=
# 线程名称前缀
spring.task.execution.thread-name-prefix=demo_Thread

配置形式:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledFuture;
//@Configuration
public class ThreadConfig {
    @Value("${task.maxPoolSize}")
    private int maxPoolSize;
    //todo 其他的相关配置都可以通过配置文件中注入
    @Bean("ThreadPoolTaskExecutor")
    public Executor myAsync() {
        final ThreadPoolTaskExecutor executor =
                new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(maxPoolSize);
        //todo  其他参数设置
        //初始化
        executor.initialize();
        return executor;
    }
}

3 创建线程后全部从ioc中获取线程池子

4 线程池处理流程:

(1) 查看核心线程池是否已满,不满就创建一条线程执行任务,核心线程数量已满就查看任务队列是否已满不满就将线程存储在任务队列中任务队列已满,就查看最大线程数量,不满就创建线程执行任务,已满就按照拒绝策略执行

(2) 拒绝策略:

  • CallerRunsPolicy():原来的线程执行

  • AbortPolicy():直接抛出异常

  • DiscardPolicy():直接丢弃

  • DiscardOldestPolicy():丢弃队列中最老的任

二: ThreadPoolTaskScheduler 

1 ThreadPoolTaskScheduler 定时调度任务线程池,处理异步任务

2 使用方式: 注入 ThreadPoolTaskScheduler的bean

 (1) 配置文件形式:..
 (2) 配置类形式:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledFuture;
@Configuration
public class ThreadPoolTaskSchedulerConfig {
    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
        final ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        //设置等待任务在关机时l候完成
        threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
        //设置等待时间为60s
        threadPoolTaskScheduler.setAwaitTerminationSeconds(60);
        return threadPoolTaskScheduler;
    }
}

3  使用ThreadPoolTaskScheduler定时任务

做普通线程池使用:

  •  submit(callable),需要执行结果

    B12
    B12

    B12是一个由AI驱动的一体化网站建设平台

    下载
  •  submit(runnable),不需要执行结果

(1) 定时任务

 添加任务内容Runnable,设置执行周期Trigger/Date,Trigger表达式百度即可

 schedule(Runnable task,Trigger)
 schedule(Runnable task,Date)

(2) 指定间隔时间执行一次任务,时间间隔是前一次任务完成到下一次任务开始,单位毫秒

 scheduleWithFixedDelay(Runnable task,long delay)

(3) 固定频率执行任务,在任务开始后间隔一段时间执行新的任务,如果上次任务么执行完成,则等待上次任务执行完成后执行下次任务

 scheduleAtFixedRate(Runnable task,long delay)

(4) 定时任务取消:

设置定时任务存储的集合,定时任务执行的结果为ScheduledFuture>,将该对象存储到集合,通过在集合中获取ScheduledFuture>对象.cancel(true)取消定时任务

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.*;
@Service
public class SchedulerService {
    @Autowired
    ThreadPoolTaskScheduler scheduler;
    /**
     * 常规线程池使用
     */
    public void tesScheduler1() throws ExecutionException, InterruptedException {
        //无返回值
        final Future demo_scheduler1 = scheduler.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("demo runnable scheduler");
            }
        });
        //无返回值
        final Future demo_scheduler2 = scheduler.submit(new Callable() {
            @Override
            public Object call() throws Exception {
                System.out.println("demo callable  scheduler");
                return "callable";
            }
        });
        System.out.println("result:" + demo_scheduler2.get());
    }
    /**
     * 定时任务
     */
    public void tesScheduler2() throws ParseException {
        //CronTrigger表达式百度即可
        scheduler.schedule(() -> {
            System.out.println("定时任务");
        }, new CronTrigger("0/1****?"));
        //创建指定时间的日期
        final Date date = new Date(2023, 3, 26, 21, 35);
        final DateFormat format = new SimpleDateFormat();
        final Date parse = format.parse("2023-03-26-21-26");
        scheduler.schedule(() -> {
            System.out.println(new Date());
        }, parse);
    }
    /**
     * 指定时间间隔执行任务,上次任务结束到下次任务开始的时间间隔
     */
    public void tesScheduler3() {
        scheduler.scheduleWithFixedDelay(() -> {
            //todo
        }, 300L);
    }
    /**
     * 固定频率执行任务,在固定一段时间后便会执行下次任务,
     * 如果时间到了上次任务还没执行完毕则等待,
     * 直到上一次任务执行完毕后立马执行下次任务
     */
    public void tesScheduler4() {
        scheduler.scheduleAtFixedRate(new FutureTask(new Callable() {
                    @Override
                    public String call() throws Exception {
                        return null;
                    }
                }),
                200);
    }
    //取消定时任务队列
    public static ConcurrentMap map = new ConcurrentHashMap<>();
    public void startTask(String k1) {
        map.compute(k1, (k, v) -> {
            if (map.containsKey(k)) return v;
            map.put(k, v);
            return v;
        });
    }
}

三 @Scheduled实现定时任务,注解开启定时任务

1 使用@EnableScheduled开启支持

2 @Scheduled标注方法

 (1)@Scheduled(fixedDelay=5000)延迟执行,5s后执行
 (2)@Scheduled(fixedRate=5000)定时执行,每隔五秒就进行执行
 (3)@Scheduled(corn="002**?") 自定义执行,corn表达式百度,常用这种执行方式,corn="002**?"每天凌晨两点开始执行定时任务

3 注意@Scheduled开启的任务是单线程的,容易阻塞

 (1) 在ioc中注入ThreadPoolTaskScheduler,则Scheduled就使用ThreadPoolTaskScheduler线程池,可以解决单线程阻塞问题
 (2) @Scheduled和@Async注解开启定时任务,在@Async("pool")中指定线程池,若是没有指定线程池会使用Spring的SimpleAsyncTaskExecutor线程池,这个线程池每次都会增加一个线程去执行任务,效率低下

四:Spring中的异步任务

1 @EnableAsync开启异步支持
2 @Async开启异步任务,指定线程池

注意:@Scheduled和@Async注解开启定时任务,在@Async("pool")中指定线程池,若是没有指定线程池会使用Spring的SimpleAsyncTaskExecutor线程池,这个线程池每次都会增加一个线程去执行任务,效率低下但是@Async单独开启异步任务,则使用的是默认的线程池,建议根据需求自定义线程池

注意:@Async的返回值只能为void或Future, 调用方和@Async不能在一个类中,否则不走aop;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncService {
    @Async
    public void showThreadName1() {
        //默认线程池
        System.out.println(Thread.currentThread().getName());
    }
    @Async("myPool")//指定线程池
    public void showThreadName2() {
        System.out.println(Thread.currentThread().getName());
    }
}

五:献上一颗自java自定义线程池:

 @Bean("myPool")
    public Executor executor(){
       return new ThreadPoolExecutor(// 自定义一个线程池
                1, // coreSize
                2, // maxSize
                60, // 60s
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(3) // 有界队列,容量是3个
                , Executors.defaultThreadFactory()
                , new ThreadPoolExecutor.AbortPolicy());
    }

java自带的线程池,缓存,固定数量的,单线程的,定时的,,,,六七种,后面续上

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

804

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

722

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

727

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

395

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

445

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

428

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16861

2023.08.03

vlookup函数使用大全
vlookup函数使用大全

本专题整合了vlookup函数相关 教程,阅读专题下面的文章了解更多详细内容。

28

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
HTML教程
HTML教程

共500课时 | 4.3万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号