我的问题陈述是我有多个监视对象,并且必须异步执行所有监视对象并将其状态报告给某些外部服务
以下是我的代码,该代码执行了10个异步任务,其中5个很快完成,而其他5个则花费更多时间。我正在使用timeoutFuture
,这是一个单独的线程,该线程在100毫秒后超时,然后用于确定较早的异步任务是否在100毫秒内完成。
我的期望是最终5个成功响应和5个失败响应应在输出中显示,但是每次我运行此代码时,始终只报告两个成功任务和8个失败任务。
有人可以让我知道我在做什么错吗?
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.IntStream;
public class TesFutureStuff {
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
public static <T> CompletableFuture<T> failAfter(long longValue) {
final CompletableFuture<T> timeoutFuture = new CompletableFuture<>();
scheduler.schedule(() -> {
final TimeoutException ex = new TimeoutException("Timeout after " + longValue);
return timeoutFuture.completeExceptionally(ex);
}, longValue, TimeUnit.MILLISECONDS);
return timeoutFuture;
}
public static void main(String[] args) {
List<CustomMonitor> arr = new ArrayList<>();
IntStream.range(0, 10).mapToObj(e -> new CustomMonitor("hello"+e, e%2==0 ? true : false)).forEach(arr::add);
arr.forEach(TesFutureStuff::submitTask);
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
private static void submitTask(CustomMonitor i) {
final CompletableFuture<CustomResponse> CustomResponseFuture = CompletableFuture.supplyAsync(() -> i.execute()).
exceptionally(ex -> {
System.out.println("help");
return new CustomResponse(ex.getMessage() , i.name);
});
CustomResponseFuture
.acceptEither(failAfter(100l), TesFutureStuff::updateStatus)
.exceptionally(throwable -> {
System.out.println("failure "+throwable.getMessage());
updateStatus(new CustomResponse(throwable.getMessage() , i.name));
return null;
})/*.getNow(null )*/;
}
static private void updateStatus(CustomResponse resp) {
System.out.println(resp+"status reported ");
}
}
class CustomResponse {
String status;
String testType;
public CustomResponse( String stat , String testType) {
status = stat;
this.testType = testType;
}
@Override
public String toString() {
return status.toString() + " " + testType.toString();
}
}
class CustomMonitor{
String name;
boolean mTimeOut ;
public CustomMonitor(String aName , boolean aShouldTimeOut) {
mTimeOut = aShouldTimeOut;
name = aName;
}
public CustomResponse execute() {
CustomResponse CustomResponse = new CustomResponse("success", name);;
if (mTimeOut) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
CustomResponse = new CustomResponse("fail", name);
}
System.out.println(Thread.currentThread().getName()+" Executing "+name);
return CustomResponse;
}
}
ForkJoinPool.commonPool-worker-2 Executing hello1
success hello1status reported
ForkJoinPool.commonPool-worker-2 Executing hello3
success hello3status reported
failure java.util.concurrent.TimeoutException: Timeout after 100
java.util.concurrent.TimeoutException: Timeout after 100 hello0status reported
failure java.util.concurrent.TimeoutException: Timeout after 100
failure java.util.concurrent.TimeoutException: Timeout after 100
java.util.concurrent.TimeoutException: Timeout after 100 hello2status reported
java.util.concurrent.TimeoutException: Timeout after 100 hello4status reported
failure java.util.concurrent.TimeoutException: Timeout after 100
java.util.concurrent.TimeoutException: Timeout after 100 hello5status reported
failure java.util.concurrent.TimeoutException: Timeout after 100
failure java.util.concurrent.TimeoutException: Timeout after 100
java.util.concurrent.TimeoutException: Timeout after 100 hello7status reported
java.util.concurrent.TimeoutException: Timeout after 100 hello6status reported
failure java.util.concurrent.TimeoutException: Timeout after 100
failure java.util.concurrent.TimeoutException: Timeout after 100
java.util.concurrent.TimeoutException: Timeout after 100 hello8status reported
java.util.concurrent.TimeoutException: Timeout after 100 hello9status reported
ForkJoinPool.commonPool-worker-1 Executing hello0
ForkJoinPool.commonPool-worker-1 Executing hello5
ForkJoinPool.commonPool-worker-3 Executing hello2
ForkJoinPool.commonPool-worker-2 Executing hello4
ForkJoinPool.commonPool-worker-3 Executing hello7
ForkJoinPool.commonPool-worker-3 Executing hello9
ForkJoinPool.commonPool-worker-1 Executing hello6
ForkJoinPool.commonPool-worker-2 Executing hello8