首页 > 其他分享 >线程池结合futureTask

线程池结合futureTask

时间:2024-09-26 22:47:47浏览次数:10  
标签:创建 FutureTask 任务 结合 线程 futureTask new 执行

概念

线程池(Thread Pool)是一种并发编程中常用的技术,用于管理和重用线程。它由线程池管理器、工作队列和线程池线程组成。

线程池的基本概念是,在应用程序启动时创建一定数量的线程,并将它们保存在线程池中。当需要执行任务时,从线程池中获取一个空闲的线程,将任务分配给该线程执行。当任务执行完毕后,线程将返回到线程池,可以被其他任务复用。

这就好比影视剧的地牢里面的烙铁,不用的时候放在火盆里,用的是直接拿,用多少拿多少,这就减少了把烙铁加热的时间了。线程比作烙铁,线程池就像火盆,保持烙铁可以直接使用;

线程池的使用

那线程池又该怎么使用呢?这里咱们结合项目介绍。

1.建立ThreadPool的config来管理线程池

(注意:项目当中线程池尽量不要使用的时候再创建,不要再业务逻辑中创建,这样每次调用这个方法都会创建一个线程池,应该在项目启动的时候就创建好)

@Configuration
public class ThreadPoolConfig {

    @Bean("labelThreadPool")
    public ThreadPoolExecutor labelThreadPoolExecutor() {
        return new ThreadPoolExecutor(20, 100, 5
                , TimeUnit.SECONDS, new LinkedBlockingQueue<>(40)
                , Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy());
    }

}

这里我们通过配置类在启动时创建一个线程池对象并把它交给spring容器管理,这样使用时直接通过注入方式就可以使用了。

2.通过FutureTask在一个异步线程中执行需要的run方法

1、 FutureTask概念
        FutureTask一个可取消的异步计算,FutureTask 实现了Future的基本方法,提供 start cancel 操作,可以查询计算是否已经完成,并且可以获取计算的结果。一个FutureTask 可以用来包装一个 Callable 或是一个runnable对象。因为FurtureTask实现了Runnable方法,所以一个 FutureTask可以提交(submit)给一个Excutor执行(excution)。
2、FutureTask使用场景
       FutureTask可用于异步获取执行结果或取消执行任务的场景。通过传入Runnable或者Callable的任务给FutureTask,直接调用其run方法或者放入线程池执行,之后可以在外部通过FutureTask的get方法异步获取执行结果,因此,FutureTask非常适合用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。另外,FutureTask还可以确保即使调用了多次run方法,它都只会执行一次Runnable或者Callable任务,或者通过cancel取消FutureTask的执行等。

    @SneakyThrows
    @Override
    public List<SubjectCategoryBO> queryCategoryAndLabel(SubjectCategoryBO subjectCategoryBO) {
        if (log.isInfoEnabled()) {
            log.info("subjectCategoryBO:{}", JSON.toJSONString(subjectCategoryBO));
        }
        SubjectCategory subjectCategory = new SubjectCategory();
        subjectCategory.setParentId(subjectCategoryBO.getId());
        subjectCategory.setIsDeleted(isDeleteCode.NO_DELETE.getCode());
        List<SubjectCategory> subjectCategoryList = subjectCategoryService.queryPrimaryCategory(subjectCategory);
        List<SubjectCategoryBO> subjectCategoryBOList = SubjectCategoryConverter.INSTANCE.convertCategoryToBoList(subjectCategoryList);
        //以上为代码可忽视


        List<FutureTask<Map<Long,SubjectCategoryBO>>> futureTaskList = new LinkedList<>();
        subjectCategoryBOList.forEach(
                category -> {
                    //创建一个futuretask用来存储任务
                    FutureTask<Map<Long, SubjectCategoryBO>> futureTask = new FutureTask<>(()->
                        getLabelList(category)
                    );
                    //存储在任务集合里面,方便取结果
                    futureTaskList.add(futureTask); 
                    //调用线程池运行任务
                    labelThreadPool.submit(futureTask);
                }
        );
        
        //通过futuretask的get获取任务运行结果
        HashMap<Long, SubjectCategoryBO> map = new HashMap<>();
        for (FutureTask<Map<Long, SubjectCategoryBO>> task : futureTaskList) {
            Map<Long, SubjectCategoryBO> categoryBOMap = task.get();
            if(CollectionUtils.isEmpty(categoryBOMap)){
                continue;
            }
            map.putAll(categoryBOMap);
        }

        //以下代码可忽视
        for (SubjectCategoryBO categoryBO : subjectCategoryBOList) {
            SubjectCategoryBO bo = map.get(categoryBO.getId());
            if(bo == null){
                continue;
            }
            categoryBO.setLabelBOList(bo.getLabelBOList());
        }
        return subjectCategoryBOList;
    }

标签:创建,FutureTask,任务,结合,线程,futureTask,new,执行
From: https://blog.csdn.net/2301_76760557/article/details/142553137

相关文章

  • 将 MongoDB 与 Cloudflare Workers 结合使用
    当我尝试使用CloudflareWorkers和MongoDB创建一个简单的项目时,我遇到了多个错误,导致集成过程变得困难。在我的研究过程中,我发现了一些讨论MongoDB和CloudflareWorkers之间的兼容性问题的文章。MongoDB和CloudflareWorkers兼容性问题我发现了一篇题为“MongoDB无法......
  • javaseday31多线程
    什么是多线程线程与进程小结并发和并行并发并行小结 多线程的实现方式方法一publicclassDemo1{publicstaticvoidmain(String[]args){//使用多线程的第一种方法/***1、创建一个类继承Thread类*2、并重写......
  • python 递归锁、信号量、事件、线程队列、进程池和线程池、回调函数、定时器
    一、python线程死锁与递归锁死锁现象所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程代码示例:fromthreadingimport......
  • Java线程池详解
    目录前言线程池概述线程池的实现线程池的构造拒绝策略任务队列线程池的工作原理线程池的监控Executors线程池工厂自定义线程池使用线程池的好处应用场景总结本文详细探讨了线程池在并发编程领域的应用,介绍了ThreadPoolExecutor的核心组件、工作原理,线程池的构造......
  • 【C++】线程池
    C++线程池1.什么是线程池?解决什么问题?C++线程池(ThreadPool)的出现主要是为了解决以下几个问题:性能:创建和销毁线程都是相对昂贵的操作,特别是在高并发场景下,频繁地创建和销毁线程会极大地降低程序的性能。通过线程池预先创建一定数量的线程并保存在内存中,可以避免频繁地创建和销......
  • 开源!Pod高负载自动打印JAVA线程堆栈
    开源!Pod高负载自动打印JAVA线程堆栈运维技术探讨  2024年08月29日17:39 广东 以下文章来源于SRE运维手记 ,作者亦零一SRE运维手记.一个在房地产、家居科技、游戏和电商行业摸爬滚打的运维老司机#sre#k8s#kubernetes#prometheus#devops01背景     在......
  • .NetCore MySqlException 多线程中(There is already an open DataReader associated w
    问题描述:其实标题只是遇到问题的其中之一,遇到三种异常信息如下:Lockwaittimeoutexceeded;tryrestartingtransaction大概意思:超过锁定等待超时;尝试重新启动事务 ThereisalreadyanopenDataReaderassociatedwiththisConnectionwhichmustbeclosedfirst.大......
  • 多线程极速导出/9字段10W行只需2秒/导入导出打印组件/功能丰富简单易用
    一、功能特点组件同时集成了导出数据到csv、xls、pdf和打印数据。所有操作全部提供静态方法无需new,数据和属性等各种参数设置采用结构体数据,极为方便。同时支持QTableView、QTableWidget、QStandardItemModel、QSqlTableModel等数据源。提供静态方法直接传入QTableView、QTab......
  • ELK中日志数据采集器Filebeat的安装和使用、Filebeat结合Logstash进行日志处理入Elast
    一、ELK中日志数据采集器Filebeat的安装和使用    Beats是数据采集的得力工具,Beats能够将数据转发至Logstash进行转换和解析。Filebeat是Beats中的一种,Filebeat是本地文件的日志数据采集器,可监控日志目录或特定日志文件(tailfile),并将它们转发给Elasticsearch或Logstats......
  • 简单聊聊线程跟进程
    简单聊聊线程跟进程在编程中,我们常常会遇到“线程”和“进程”这两个词。它们都是帮助我们同时执行多个任务的工具,但它们之间有一些重要的区别。让我们用简单的语言来聊聊这两个概念,同时提供一些代码示例,让你更容易理解。 什么是进程?进程可以看作是计算机上运行的一个独立......