package com.demo.data;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
public class EitherCancelAllDemo {
static boolean isEmptyOrZero(Integer v) {
return v == null || v == 0;
}
public static void main(String[] args) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(4);
try {
List<CompletableFuture<Integer>> futures = Arrays.asList(
CompletableFuture.supplyAsync(() -> run("A", 3000, 42), pool),
CompletableFuture.supplyAsync(() -> run("B", 2000, 7), pool),
CompletableFuture.supplyAsync(() -> run("C", 1000, 0), pool), // 这个会触发取消
CompletableFuture.supplyAsync(() -> run("D", 4000, 99), pool));
AtomicBoolean cancelled = new AtomicBoolean(false);
for (CompletableFuture<Integer> f : futures) {
f.whenComplete((res, ex) -> {
if (ex == null && isEmptyOrZero(res)) { // 任一任务结果空/0
if (cancelled.compareAndSet(false, true)) { // 只触发一次
System.out.println("发现空/0 结果,取消所有任务");
futures.forEach(other -> other.cancel(true)); // 已完成的 cancel 无副作用
}
}
});
}
try {
// 等齐所有任务;任一被取消/异常则整体失败
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
List<Integer> results = futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
if (results.stream().anyMatch(EitherCancelAllDemo::isEmptyOrZero)) {
// 兜底:后完成者返回空/0(对方已完成,来不及打断)
System.out.println("存在空/0 结果(后完成者),整体失败: " + results);
} else {
System.out.println("全部有效,等齐完成: " + results);
}
} catch (CancellationException e) {
System.out.println("某任务结果为空/0,已打断全部,整体失败");
}
} finally {
pool.shutdownNow();
pool.awaitTermination(5, TimeUnit.SECONDS);
}
}
static Integer run(String name, int millis, int result) {
try {
for (int i = 0; i < millis / 100; i++) {
Thread.sleep(100);
if (Thread.currentThread().isInterrupted()) {
System.out.println(name + " 收到中断,提前退出");
return null;
}
}
System.out.println(name + " 完成,结果=" + result);
return result;
} catch (InterruptedException e) {
System.out.println(name + " 被中断,退出");
return null;
}
}
}