步骤总结
- 创建 List 泛型中为 Future ,Future 的泛型指定为将要接收的返回值类型。
- 创建线程池。
- 对要循环的处理的数据进行 foreach 操作。
- 在上一步的循环处理操作中为 Future 的 List 添加元素,返回值从线程池对象的 submit 方法中通过 Callable 的方式获取或使用 lambda 表达式操作。
- 在 Callable 或 lambda 表达式 中编写要处理的业务逻辑并将返回值返回。
- 在 foreach 循环外停止线程池。
- while 循环,如果线程没有处理结束则持续等待一定时间,直到结束。
示例代码
仅供参考
// Future List 创建
List<Future<ByteArrayOutputStream>> futureList = new ArrayList<>();
// 线程池创建
ExecutorService executor = Executors.newFixedThreadPool(20);
// 在循环中处理业务内容 cycleNumber为要循环的内容,可以为业务数据也可以不是
for (final Integer index : cycleNumber) {
futureList.add(executor.submit(() -> {
// 业务处理
。。。。。。。。。
。。。。。。。。。
。。。。。。。。。
ByteArrayOutputStream needBytes = new ByteArrayOutputStream();
wb.write(needBytes);
// 返回需要的
return needBytes;
}));
}
// 停止
executor.shutdown();
// 等待线程完成以及对应的业务处理
while (!executor.isTerminated()) {
try {
// 等待 200 毫秒
executor.awaitTermination(200, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
}
// 其他额外的处理
。。。。。。。
。。。。。。
。。。。。。
}
for (Future<ByteArrayOutputStream> future : futureList) {
// 业务处理
。。。。。。。。。。
。。。。。。。。。。
。。。。。。。。。。
}
// 最终处理 流关闭等操作
。。。。。
自定义实体返回示例:
// 创建Future List
List<Future<CExportModel>> futureList = new ArrayList<>();
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(15);
// 这里循环业务数据 csList为要循环的业务数据
for (CEntity cs : csList) {
futureList.add(executor.submit(() -> {
// 业务处理
。。。。。。。
。。。。。。
。。。。。。
// 这里返回是以 new 的形式,根据自己实际情况返回即可
return new CExportModel(。。。。。);
}));
}
// 停止
executor.shutdown();
// 循环等待结束
while (!executor.isTerminated()) {
try {
// 等待200 毫秒
executor.awaitTermination(200, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
log.error(e);
}
}
// 循环处理最终得到的业务数据
Iterator<Future<CExportModel>> iter = futureList.iterator();
while (iter.hasNext()) {
Future<CExportModel> future = iter.next();
if (future.isDone()) {
// 如果已完成 则要做的处理
}
}
在 futureList.add(executor.submit()中submit提交的只要符合泛型即可 直接在 submit 中 new 对象,即对应的构造函数也可。
一种特殊的去除操作
while (!futureList.isEmpty()) {
futureList.removeIf(Future::isDone);
}
Callable 方式示例
List<Future<Integer>> futureList = new ArrayList<>();
ExecutorService executor = Executors.newFixedThreadPool(20);
for (Integer cycle : cycleNumberList) {
futureList.add(executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
// 业务处理
。。。。。。。。。。
。。。。。。。。。。
。。。。。。。。。。
return cycle;
}
}));
}
executor.shutdown();
try {
while (!executor.awaitTermination(1, TimeUnit.SECONDS)) {
// wait
}
} catch (InterruptedException e) {
log.error(e);
}