标签: completable-future

CompletableFuture何时实际完成?

这是MCVE:

public static void main(String[] args) {
    CompletableFuture<String> r1 = CompletableFuture.supplyAsync(() -> {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "41";
    });
    CompletableFuture<String> r2 = CompletableFuture.supplyAsync(() -> "42");
    CompletableFuture<String> r3 = CompletableFuture.supplyAsync(() -> {
        System.out.println("I'm called.");
        return "43";
    });
    CompletableFuture.allOf(r1, r2, r3).thenRun(() -> { System.out.println("End."); });
    Stream.of(r1, r2, r3).forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)

有点好奇,没有实际完成CompletableFutureallOf(...),例如调用它join(),我得到以下输出:

I'm called.
java.util.concurrent.CompletableFuture@<...>[Not completed, 1 dependents]
java.util.concurrent.CompletableFuture@<...>[Completed normally]
java.util.concurrent.CompletableFuture@<...>[Completed normally]
Run Code Online (Sandbox Code Playgroud)

我可以知道是什么导致JVM处理/认为r11(估计数量)依赖CompletableFuture …

java completable-future

7
推荐指数
1
解决办法
3925
查看次数

java-8 CompletableFuture回调调用的延迟不合理

第一个回调电话很快,其余的延迟~50ms(非加法),我不知道为什么.

public class CfTest {

    final static long t0 = System.nanoTime();

    public static void main(String[] args) {
        CompletableFuture<Integer> cf1 = CompletableFuture.supplyAsync(()->{sleep(2000); return 100;});
        CompletableFuture<Long> cf2 = CompletableFuture.supplyAsync(()->{sleep(1000); return 1L;});
        CompletableFuture<Long> cfs = cf1.thenCombine(cf2, (a,b)->a+b);
        cfs.thenAccept(x->debug("a1. " + x)); // Async process, sync when complete
        cfs.thenAccept(x->debug("a2. " + x)); // Async process, sync when complete
        cfs.thenAcceptAsync(x->debug("a3. " + x)); // Async process, async after complete too
        debug("b. " + cfs.join()); // Wait and process
        debug("c. " + cfs.join()); // Wait and …
Run Code Online (Sandbox Code Playgroud)

java multithreading java-8 completable-future

7
推荐指数
1
解决办法
828
查看次数

您如何访问已传递给CompletableFuture allOf的已完成期货?

我试图掌握Java 8 CompletableFuture.我怎样才能将这些人加入到"allOf"之后再归还给他们.下面的代码不起作用,但让你知道我尝试过的.

在javascript ES6中我会这样做

Promise.all([p1, p2]).then(function(persons) {
   console.log(persons[0]); // p1 return value     
   console.log(persons[1]); // p2 return value     
});
Run Code Online (Sandbox Code Playgroud)

到目前为止我在Java方面的努力

public class Person {

        private final String name;

        public Person(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

    }

@Test
public void combinePersons() throws ExecutionException, InterruptedException {
    CompletableFuture<Person> p1 = CompletableFuture.supplyAsync(() -> {
        return new Person("p1");
    });

    CompletableFuture<Person> p2 = CompletableFuture.supplyAsync(() -> {
        return new Person("p1");
    });

    CompletableFuture.allOf(p1, p2).thenAccept(it -> System.out.println(it));

}
Run Code Online (Sandbox Code Playgroud)

java java-8 completable-future

7
推荐指数
1
解决办法
7043
查看次数

执行CompletableFuture的多个thenAccept块的顺序是什么

所以我有一个方法返回一个CompletableFuture.在返回之前,此方法添加一个块,thenAcceptCompletableFuture完成后执行该块.

此方法的调用者还添加了另一个块thenAccept.显然,这可以继续多个链式调用.

调用CompletionStage返回的顺序是什么thenAccept?是否保证是添加它们的顺序?如果没有,如何保证它们按照添加顺序执行?

PS:我根据自己的经验CompletableFuture本文提出这个问题

java java-8 completable-future

7
推荐指数
1
解决办法
1181
查看次数

为什么在异常完成之前调用get()会等待异常执行?

回答这个问题的时候,我注意到了一个奇怪的行为CompletableFuture:如果你有一个CompletableFuture cf和一个调用链cf.exceptionally(),调用cf.get()似乎表现得很奇怪:

  • 如果在异常完成之前调用它,它会exceptionally()在返回之前等待块的执行
  • 否则,它会立即失败 ExecutionException

我错过了什么或这是一个错误吗?我在Ubuntu 17.04上使用Oracle JDK 1.8.0_131.

以下代码说明了这种现象:

public static void main(String[] args) {
    long start = System.currentTimeMillis();
    final CompletableFuture<Object> future = CompletableFuture.supplyAsync(() -> {
        sleep(1000);
        throw new RuntimeException("First");
    }).thenApply(Function.identity());

    future.exceptionally(e -> {
        sleep(1000);
        logDuration(start, "Exceptionally");
        return null;
    });

    final CompletableFuture<Void> futureA = CompletableFuture.runAsync(() -> {
        try {
            future.get();
        } catch (Exception e) {
        } finally {
            logDuration(start, "A");
        }
    });

    final CompletableFuture<Void> futureB = CompletableFuture.runAsync(() …
Run Code Online (Sandbox Code Playgroud)

java asynchronous future java-8 completable-future

7
推荐指数
1
解决办法
672
查看次数

如何在 Mockito 中模拟 CompletableFuture 的完成

CompletableFuture我想模拟当 a成功完成时正在调用一些代码。

我有这门课:

public class MyClassImplementRunner implements Runnable {

    private final String param1;

    public MyClassImplementRunner(String param1) {
        this.param1 = param1;
    }

    public static CompletableFuture<Void> startAsync(String param1) {

        return CompletableFuture.runAsync(
            new MyClassImplementRunner(param1)).whenComplete(
            (response, throwable) -> {
                //some code when complete
            });

        @Override
        public void run () {
            //the runnable code
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的 Junit 中(使用 Mockito 和 Java 8),我需要模拟它

//some code when complete 
Run Code Online (Sandbox Code Playgroud)

当 Future 成功完成时调用。

您能否提供一些关于如何实现这一目标的指示?

java mockito completable-future

7
推荐指数
1
解决办法
2万
查看次数

使用 CompletableFuture 回调是否有性能优势?

CompletableFuture 允许为异步调用提供回调。您可以创建一长串回调,其中每个异步调用将在完成时触发下一个回调。这被认为是编写异步代码的更好方法,而不是使用 Future,在 Future 中,您必须阻塞线程才能在触发下一个计算之前获取第一个计算的结果。

我可以理解 Completable Futures 中的回调链可以提供更具可读性的代码的论点,但我想知道这种方法是否也有性能优势,或者它只是一个语法糖?

例如,考虑以下代码:

    ExecutorService exec = Executors.newSingleThreadExecutor();
    CompletableFuture.supplyAsync(this::findAccountNumber, exec)
                     .thenApply(this::calculateBalance)
                     .thenApply(this::notifyBalance)
                     .thenAccept((i)->notifyByEmail())
                     .join();
Run Code Online (Sandbox Code Playgroud)

在此代码中,在完成calculateBalance()之前无法启动findAccountNumber(),因此回调链中的下一个方法基本上calculateBalance()被阻塞,依此类推。findAccountNumber()它比以下内容如何更好(性能方面):

    ExecutorService exec = Executors.newSingleThreadExecutor();
    Future<Integer> accountNumberFuture = exec.submit(findAccountNumberCallable);
    Integer accountNumber = accountNumberFuture.get();
    Future<String> calculateBalanceFuture = exec.submit(calculateBalanceCallable(accountNumber);
    ....
    ....

Run Code Online (Sandbox Code Playgroud)

java completable-future

7
推荐指数
1
解决办法
4166
查看次数

通过 CompletableFuture 调用包含的类方法时,WebTarget Bean 实例化在 Spring 中失败

我正在从我的 Spring Boot 应用程序调用不同的其他 Web 服务。为了提高性能而不是顺序调用它们,我想实现CompletableFuture.supplyAsync()异步执行。

我正在调用的服务,其中一些是内部的,一些是外部的。因此,对于内部,我直接调用它们的 api 接口,这些接口存在于 Maven 依赖项中,而对于外部接口,我正在使用javax.ws.rs.client.WebTarget

在实现调用时,CompletableFuture.supplyAsync()内部的客户端类会成功执行,而具有依赖关系的客户端类则会WebTarget因未创建 bean 而@Inject失败。scopedTarget.XXService_nameXX_wt

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.charityserv_wt': Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.ws.rs.client.WebTarget]: Factory method 'target' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.coreContext': Scope 'request' is not active for the current thread
Run Code Online (Sandbox Code Playgroud)

调用代码:

CompletableFuture<SearchResult> future = CompletableFuture.supplyAsync(() -> searchServiceClientImpl.getsearchSearchRequest(encryptedAccountNumber));
Run Code Online (Sandbox Code Playgroud)

服务客户端类:

@Component
public class …
Run Code Online (Sandbox Code Playgroud)

java spring jax-rs spring-boot completable-future

6
推荐指数
0
解决办法
1336
查看次数

Junit:如何覆盖 CompletableFuture 代码

我是 Junit 新手,最近遇到了这个问题。无论我在代码中使用 CompletableFuture,我都无法编写测试用例。就像下面的Java文件一样

更新

审计服务.java

@Autowired
Executor existingThreadPool;

@Override
public void auditData(List<ErrorDetails> alertList) {
    CompletableFuture.runAsync(() -> {
        if (alertList.isEmpty())
            //privateMethodCall1
        else
           //privateMethodCall2
    }, existingThreadPool);
}
Run Code Online (Sandbox Code Playgroud)

我点击此链接并尝试了下面的解决方案,但仍然出现 NPE for CompletableFuture 类似下面的错误。

审计服务测试.java

@InjectMock
AuditService auditService;

@Mock
private CompletableFuture<Void> completableFuture = null;

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
    completableFuture = CompletableFuture.runAsync(new Runnable() {
        @Override
        public void run() {}
    },Executors.newSingleThreadExecutor());
}

@Test
public void shouldAuditData() {
    List<ErrorDetails> alertList = new ArrayList();
    auditService.auditData(alertList);
}
Run Code Online (Sandbox Code Playgroud)

错误

java.lang.NullPointerException
    at java.util.concurrent.CompletableFuture.screenExecutor(CompletableFuture.java:415)
    at java.util.concurrent.CompletableFuture.runAsync(CompletableFuture.java:1858)
    at …
Run Code Online (Sandbox Code Playgroud)

java junit mockito spring-boot completable-future

6
推荐指数
1
解决办法
2万
查看次数

Java 8 到 Java 17 ThreadLocal 问题

我的代码在 Java 8 中运行良好,但是当我将其迁移到 Java 17 时,它就不起作用了。它涉及 ThreadLocal 和 CompletableFuture.runAsync。

以下是课程:

public class UriParameterHandler {
}

public class DateRangeEntity {
    public String getCurrentDate(){
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        return dtf.format(now);
    }
}

public class SessionHandler {

    private static ThreadLocal<SessionHandler> instance = new InheritableThreadLocal<>();
    private UriParameterHandler uriParameterHandler;
    private DateRangeEntity dateRangeEntity;

    private SessionHandler() {
        instance.set(this);
    }

    public static void initialize() {
        SessionHandler handler = new SessionHandler();
        handler.uriParameterHandler = new UriParameterHandler();
    }

    public static UriParameterHandler getUriParameterHandler() {
        return instance.get().uriParameterHandler; …
Run Code Online (Sandbox Code Playgroud)

java multithreading thread-local completable-future java-17

6
推荐指数
1
解决办法
956
查看次数