java 线程池实现多线程处理list数据

这篇具有很好参考价值的文章主要介绍了java 线程池实现多线程处理list数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

newFixedThreadPool线程池实现多线程

		List<PackageAgreementEntity> entityList = new CopyOnWriteArrayList<>();
        //多线程   10个线程
        //int threadNum = 10;
        int listSize = 300;
        List<List<PackageAgreementDto>> splitData = Lists.partition(packageAgreementList, listSize);
        //CountDownLatch latch = new CountDownLatch(splitData.size());
        //声明线程池对象
        ExecutorService touchWorker = Executors.newFixedThreadPool(splitData.size());
        //不加这个会导致线程不安全,丢失数据
        Semaphore semaphore = new Semaphore(splitData.size());//定义几个许可
        List<PackageAgreementErroDto> errorList2 = new CopyOnWriteArrayList();

        for (int i = 0; i < packageAgreementList.size(); i++) {
            final  int j = i;
            semaphore.acquire();
            touchWorker.execute(()->{
                try {
                        logger.info(Thread.currentThread().getName()+ j);
                        logger.info("数据第几条:" + j);
                        //校验物料、供应商、ou、地点信息是否存在
                        packageAgreementService.checkMultiData(packageAgreementList.get(j), j ,user, dateFormat,  errorList2, entityList);

                        semaphore.release();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            });
        }
        //每隔10s检测线程是否执行结束
        boolean flag = touchWorker.awaitTermination(10, TimeUnit.SECONDS);
         if(!flag){
            logger.info("一揽子协议价格录入完成!");
        }

需要注意的问题点,多线程处理List数据可能发生线程不安全,
引入CopyOnWriteArrayList,Semaphore解决,或者加锁解决问题;所有线程执行完毕后再进行后续业务的处理,引入awaitTermination()方法。

发现上述逻辑有问题,被其他资料误导,awaitTermination并不是上述描述的作用。为了保证线程池的所有线程执行完毕,优化后代码如下:

		AtomicInteger count = new AtomicInteger();
/**
         * 采用线程池处理数据,减少时耗,线程池数量为10
         */
        int threadNum = 10;
        ExecutorService touchWorker = Executors.newFixedThreadPool(threadNum);
        Semaphore semaphore = new Semaphore(threadNum);//定义几个许可

        for(TeamWorkMainConfirmInfoDto confirmInfoDto:list){
            semaphore.acquire();
            touchWorker.execute(()->{
                try {

                    //根据主表id查询要导出的子流程信息
                    List<TeamWorkInfoExportDto> slaveInfoDtoList = teamWorkSlaveInfoService.findExportSlaveListByMainId(confirmInfoDto.getId());
                    lock.lock();
                    if(slaveInfoDtoList != null && slaveInfoDtoList.size() >0){
                        for(TeamWorkInfoExportDto slaveInfoDto:slaveInfoDtoList){
                            exportList.add(slaveInfoDto);
                        }
                    }else{  //如果没有子流程数据,添加主流程数据到导出数据中
                        TeamWorkInfoExportDto mainDto = new TeamWorkInfoExportDto();
                        mainDto.setTaskBookName(confirmInfoDto.getTaskBookName());
                        exportList.add(mainDto);

                    }

                    count.getAndIncrement();
                    logger.info("第" + count + "条数据!");
                    lock.unlock();
                    semaphore.release();
                } catch (Exception e){
                    e.printStackTrace();
                }
            });

        }

        //判断所有线程是否都执行完
        //EndTask endTask = new EndTask(list.size());
        //touchWorker.execute(endTask);
        while(true) {
            if(list.size() == count.intValue()) {

                logger.info("研发任务书多线程导出完成!");
                break;

            }else {
                logger.info("研发任务书导出线程池的任务没有完成,等待。。。");
                Thread.sleep(1000);
            }
        }
        touchWorker.shutdown();

count 未使用静态变量的原因:使用static静态变量还需要在线程池结束后初始化,而且可能出现多用户竞争资源的现象导致出现问题。而且AtomicInteger 能有效保证原子性(用于后续验证所有线程执行完成)文章来源地址https://www.toymoban.com/news/detail-667264.html

到了这里,关于java 线程池实现多线程处理list数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java 多线程批量处理数据

    1 需求 在项目开发中需要处理100万多的数据,这些数据需要从mysql数据库中读取出来,再通过调用其他平台的接口推送数据。由于时间紧迫,数据需要在短时间内完成推送,采用单线程推送很慢,所以采用多线程推送来提高效率。 2 配置多线程 2.1 application.yml 2.2 创建ThreadPoo

    2024年02月22日
    浏览(43)
  • java 多线程处理大量并发数据

    Java中多线程是一种处理数据的常见方式,它可以同时执行多个线程以提高程序的性能和效率。下面是一个使用多线程处理数据的示例代码: 在上面的代码中,我们创建了一个数组 data 来存储待处理的数据。然后,我们创建了一个线程数组 threads ,用于存储要执行的线程。 通

    2024年02月09日
    浏览(53)
  • Java8对List集合中的数据进行过滤处理

    目录 0.需求场景 1.编码实现         假设有这样一个需求,将List中所有超过 35 岁的员工剔除,该如何实现呢?我们可以利用 Java8 的流式编程,轻松的实现这个需求。         当然也不局限与上述场景,对应的处理方法适用与根据 List 中元素或元素的属性,对 List 进行处

    2024年02月15日
    浏览(55)
  • Java使用线程池批量处理数据操作

    疑问思路: 1.如何保证数据按顺序批量处理 2.如何保证数据全部处理完统一返回 3.如何保证是多任务异步操作 4.如何提高运行效率,减少运行时间 1.使用ArrayList 插入数据有序且可重复 2.CountDownLatch / Future / CompletableFuture 3.多线程 4.线程池创建多线程 具体流程: 获取需要进行批

    2024年02月09日
    浏览(63)
  • JAVA多线程处理for循环数据

    对for循环内数据启用多线程执行,主线程与子线程无先后顺序 执行结果: 对for循环内数据启用多线程执行,主线程在所有子线程执行完成之后执行 执行结果: 对for循环内数据启用多线程执行,主线程在所有子线程执行完成之后执行 执行结果: 4. JAVA多线程10个线程处理100

    2024年02月11日
    浏览(54)
  • for循环内线程池并发执行任务,等到子线程全部处理完任务,主线程在执行java的实现方式

    for循环内线程池并发执行任务,等到子线程全部处理完任务,主线程在执行 方式一 使用 CountDownLatch 在 Java 中,您可以使用 CountDownLatch 来实现主线程等待子线程执行完成的功能。CountDownLatch 是一个同步工具类,它允许一个或多个线程等待其他线程完成操作后再继续执行。 具

    2024年02月11日
    浏览(43)
  • 流式计算中的多线程处理:如何使用Kafka实现高效的实时数据处理

    作者:禅与计算机程序设计艺术 Apache Kafka 是 Apache Software Foundation 下的一个开源项目,是一个分布式的、高吞吐量的、可扩展的消息系统。它最初由 LinkedIn 开发并于 2011 年发布。与其他一些类似产品相比,Kafka 有着更强大的功能和活跃的社区支持。因此,越来越多的人开始使

    2024年02月12日
    浏览(63)
  • java中多线程去跑海量数据使用线程池批量ThreadPoolExecutor处理的方式和使用Fork/Join框架的方式那种效率高?

    在Java中,使用线程池(ThreadPoolExecutor)和使用Fork/Join框架来处理海量数据的效率取决于具体的应用场景和需求。下面是一些需要考虑的因素: 任务类型:如果任务是CPU密集型的,那么使用Fork/Join框架可能更高效,因为它可以自动进行任务分割和并行处理。如果任务是I/O密集

    2024年02月10日
    浏览(48)
  • 如何实现一个线程安全的list

    开发过程中,较常使用非线程安全的list,但遇到特定场景需要使用线程安全的,该如何使用呢? 是使用Vector,还是说有更好的实现方式? Vector的底层与ArrayList类似.都是以动态数组的方式进行对象的存储,Vector与ArrayList的区别在于Vector是线程同步操作安全的,因为官方在可能

    2024年02月02日
    浏览(37)
  • Java入门7(异常处理,list集合)

    一般来讲,程序出现错误的时候,大致情况有三种: 语法错误 运行时错误,指的是各程序运行的时候,出现的一些没有想到的问题,比如除数为0,比如数组下标越界等等 逻辑错误,运行结果和与其结果不一致,俗称bug ⭐Java中的异常处理机制主要用于处理运行时错误 ​运行

    2024年02月03日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包