线程池多线程如果有任务出现异常,怎么统计成功的个数

工作中使用到了CountDownLatch countDownLatch =new CountDownLatch (20);让线程池去跑20个任务,不管有无异常,run()方法都必须有finally()方法,在finally方法里面执行 countDownLatch.countDown()让总任务数减少1.

这样子的话就存在,外面使用countDownLatch.await()方法后,不知道具体成功了多少个任务。

我暂时的解决方案是:countDownLatch.await()方法,再自己去数据库查询刚才多线程任务插入到数据库的数据有多少个就可以判断有多少个任务成功了,当然这个解决方案肯定不通用,但是对于我多线程任务就是往数据库加数据的情况是适用的。

应该还有其他解决方案,后面再探寻:看能不能适用 有返回值的线程,比如出现异常返回一个标识。

接着再来:

 

可以使用有返回值的Callable接口来实现该功能。Callable接口的call()方法有返回值Object.需要注意的点是:get是阻塞的,等待有返回到Future中才会继续,不get不会阻塞

package com.tianrun.utils;

import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;

public class CallableTask implements Callable {
    private String name;
    private CountDownLatch countDownLatch;

    public CallableTask(String name,CountDownLatch countDownLatch) {
        this.name = name;
        this.countDownLatch=countDownLatch;
    }

    @Override
    public Object call() {
        try{
            Thread.sleep(2000);
            if(name.equals("5")){
               ResultDemo resultDemo=new ResultDemo();
               resultDemo.setSuccess(false);
               return resultDemo;
            }
        }catch (Exception e){
            System.out.println("出现异常了...");
        }finally {
            countDownLatch.countDown();
        }
        ResultDemo resultDemo=new ResultDemo();
        resultDemo.setSuccess(true);
        return resultDemo;
    }
}

 

package com.tianrun.utils;

public class ResultDemo {
    /**
     * 响应编码
     */
    private boolean success;
    /**
     * 提示消息
     */
    private String message;

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

 

 

package com.tianrun.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;


public class TestCallableTask {
    public static void main(String[] args)  throws Exception {
        //创建3个callable有返回值的任务,然后放到池子里面执行,我需要任务都执行完后,再打印成功个数和失败个数
        //1、任务个数
        CountDownLatch countDownLatch=new CountDownLatch(20);
        ExecutorService executorService=Executors.newFixedThreadPool(20);
        List<Future<ResultDemo>> futureList=new ArrayList<>();
        List<String> successList=new ArrayList<>();
        List<String> failList=new ArrayList<>();
        for(int i=0;i<20;i++){
            CallableTask callableTask=new CallableTask(i+"",countDownLatch);
            Future future=executorService.submit(callableTask);
            futureList.add(future);
            //System.out.println(future.get().toString());   不能要这句代码,不然的话,这里会阻塞,会导致必须一个任务一个任务执行完后,再for循环
        }
        countDownLatch.await();  //确保线程池任务执行完后,再统计
        //关闭线程池,节约资源
        executorService.shutdown();
        futureList.forEach(future -> {
            try {
                ResultDemo result=future.get();  //这里获取返回值    使用ResultDemo来接收值,是因为之前定义的时候就是 List<Future<ResultDemo>> futureList=new ArrayList<>();    futureList.add(future);
                if (result.isSuccess()){
                    successList.add("1");
                }else {
                    failList.add("1");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        System.out.println("任务执行完毕成功数量:"+successList.size()+"|失败数量:"+failList.size());
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,使用线程池可以方便地开启多线程来处理任务Java提供了几种常见的线程池创建方式,其中推荐使用ThreadPoolExecutor的构造器来创建适合业务场景的线程池。\[1\] 常见的线程池创建方式包括: 1. FixedThreadPool(固定线程池):线程池的大小一旦达到固定数量就会保持不变,适用于需要控制并发线程数量的场景。 2. SingleThreadExecutor(单线程化的线程池):只有一个线程的线程池任务按照提交的次序顺序执行,适用于需要按顺序执行任务的场景。 3. CachedThreadPool(可缓存线程池):线程池的大小可以根据需要自动调整,适用于需要处理大量短期任务的场景。 使用线程池的好处是可以提前创建好多个线程,放入线程池中,使用时直接获取,使用完后放回池中,避免频繁创建和销毁线程,实现线程的重复利用。线程池能够独立负责线程的创建、维护和分配,提高了线程的执行效率和资源利用率。\[2\]\[3\] #### 引用[.reference_title] - *1* *2* *3* [java多线程(线程池)使用总结](https://blog.csdn.net/domine/article/details/127342754)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值