CompletableFuture无法按预期工作

时间:2018-12-14 06:25:13

标签: java asynchronous lambda java-8 completable-future

我试图从Java 8中了解CompletableFuture的工作原理。下面的代码按预期工作

CompletableFuture.supplyAsync(() -> {
    System.out.println("supplyAsync Thread name " + Thread.currentThread().getName());
    return "str";
}).thenApply(str -> {
    System.out.println("thenApply Thread name " + Thread.currentThread().getName());
    return str;
}).thenApply(str1 -> {
    System.out.println("thenApply Thread name " + Thread.currentThread().getName());
    return str1;
}).thenAccept(str3 -> {
    System.out.println("thenAccept Thread name " + Thread.currentThread().getName());
});
System.out.println("Thread name " + Thread.currentThread().getName());

输出:

supplyAsync Thread name ForkJoinPool.commonPool-worker-1
thenApply Thread name main
thenApply Thread name main
thenAccept Thread name main
Thread name main

但是当我进行一些计算时,它无法按预期工作,如果我缺少某些内容,请纠正我。

CompletableFuture.supplyAsync(() -> {
    System.out.println("supplyAsync Thread name " + Thread.currentThread().getName());
    long val = 0;
    for (long i = 0; i < 1000000; i++) {
        val++;
    }
    return "str";
}).thenApply(str -> {
    System.out.println("thenApply Thread name " + Thread.currentThread().getName());
    long val = 0;
    for (long i = 0; i < 1000000; i++) {
        val++;
    }
    return str;
}).thenApply(str1 -> {
    System.out.println("thenApply Thread name " + Thread.currentThread().getName());
    long val = 0;
    for (long i = 0; i < 1000000; i++) {
        val++;
    }
    return str1;
}).thenAccept(str3 -> {
    System.out.println("thenAccept Thread name " + Thread.currentThread().getName());
    long val = 0;
    for (long i = 0; i < 1000000; i++) {
        val++;
    }
});

System.out.println("Thread name " + Thread.currentThread().getName());

输出为:

supplyAsync Thread name ForkJoinPool.commonPool-worker-1
Thread name main

我同意不将子线程加入主线程。我的理解是子线程应该独立于主线程打印语句。问题是为什么它根本不打印。

1 个答案:

答案 0 :(得分:2)

说明

您没有将子线程CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream inStream = MainActivity.context.getResources().openRawResource(R.raw.mysslcert); Certificate ca = cf.generateCertificate(inStream); inStream.close(); String keyStoreType = KeyStore.getDefaultType(); KeyStore ks = KeyStore.getInstance(keyStoreType); ks.load(null, null); ks.setCertificateEntry("ca", ca); String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(ks); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null,tmf.getTrustManagers(), null); URL url = new URL("https://myAPIurl.com/MyFunction"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(sslContext.getSocketFactory()); BufferedReader buffReader = new BufferedReader(new InputStreamReader(conn.getInputStream())); 加入主线程。因此一旦线程ForkJoinPool.commonPool-worker-1完成,它就会被杀死。

解决方案

尝试在您可实现的将来在代码中的某个时刻致电main。请注意,此方法正在阻塞.join()线程。因此,连接点之后的执行将被挂起,直到子线程完成其执行为止。

main

将打印:

CompletableFuture.supplyAsync(() -> {
    System.out.println("=> supplyAsync Thread name " + Thread.currentThread().getName());
    // ...
}).thenApply(str -> {
    System.out.println("thenApply Thread name " + Thread.currentThread().getName());
    // ...
}).thenApply(str1 -> {
    System.out.println("thenApply Thread name " + Thread.currentThread().getName());
    // ...
}).thenAccept(str3 -> {
    System.out.println("thenAccept Thread name " + Thread.currentThread().getName());
    // ...
}).join()

如果您不希望最后一个supplyAsync Thread name ForkJoinPool.commonPool-worker-1 thenApply Thread name ForkJoinPool.commonPool-worker-1 thenApply Thread name ForkJoinPool.commonPool-worker-1 thenAccept Thread name ForkJoinPool.commonPool-worker-1 Thread name main 依赖于子线程的执行,则将System.out.println(...)分配给一个变量,并将其加入main的最后:

CompletableFuture