如何在 Java 中实现非阻塞 Futures

Tha*_*nga 2 java multithreading future nonblocking executorservice

Java Future 对象用于获取由并行线程(Executors)执行的异步计算的结果。我们调用 Future.get() 方法并等待结果准备就绪。此示例显示了从 Future 检索结果的非阻塞方式。java-implement-java-non-blocking-futures

NonBlockingExecutor executor = new NonBlockingExecutor(Executors.newSingleThreadExecutor());

NonBlockingFuture<Integer> future = executor.submitNonBlocking(new Callable<Integer>() {

            @Override
            public Integer call() throws Exception {
                String threadName = Thread.currentThread().getName();
                System.out.println(threadName);
                //print -> pool-1-thread-1
                return 1;
            }
});

future.setHandler(new FutureHandler<Integer>() {

       @Override
       public void onSuccess(Integer value) {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName);
            //print -> pool-1-thread-1
       }

       @Override
       public void onFailure(Throwable e) {
            System.out.println(e.getMessage());
       }
 });

 Thread.sleep(50000);
Run Code Online (Sandbox Code Playgroud)

在此 onSuccess() 方法在并行执行完成后被调用。问题是 onSuccess() 方法没有在主线程上运行。我想在主线程上执行 onSuccess() 方法。我怎样才能解决这个问题。谢谢

Joh*_*int 6

这由CompletableFutures支持。

    CompletableFuture.runAsync(() -> {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName);
        //print -> pool-1-thread-1
    }).whenComplete((task, throwable) -> {
        if(throwable != null) {
           System.out.println(e.getMessage());
        } else {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName);
            //print -> pool-1-thread-1
        }
    });
Run Code Online (Sandbox Code Playgroud)

这里需要注意的是,未来将whenComplete在执行线程而不是提交线程上运行任务。


War*_*Dew 3

a 的要点Future是相关的计算是在单独的线程中执行的。该onSuccess方法是该单独线程表明其已完成执行计算的一种方式。主线程调用 是没有意义的onSuccess,因为主线程不执行计算并且不知道计算何时完成。

在主线程中,如果您想等待计算完成并获取结果,请调用get()。如果您想检查计算是否完成,如果尚未完成则继续执行其他操作,请调用isDone()get(long, TimeUnit)。如果您想终止计算,无论计算是否完成,请调用cancel()