我试图从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
我同意不将子线程加入主线程。我的理解是子线程应该独立于主线程打印语句。问题是为什么它根本不打印。
答案 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