CompletableFuture-异步任务执行错误吗?

时间:2018-07-21 14:56:33

标签: java asynchronous java-8 completable-future

我的问题陈述是我有多个监视对象,并且必须异步执行所有监视对象并将其状态报告给某些外部服务

  • 成功表示任务是否在100毫秒内执行,
  • 对于耗时超过100毫秒的任务,应报告失败或超时

以下是我的代码,该代码执行了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

0 个答案:

没有答案