工作中使用到了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());
}
}