CompletableFuture.supplyAsync()
以上方法需要一个返回值,然后可以用get方法获取异步任务的结果。但是获取结果时是同步的。如果你写get的地方非常近,就有可能你的异步方法还没执行完毕,还没结果呢,你就开始获取了。所以就会导致变成了同步操作。所以这个get调用,可以放在几个任务之后,别放的离自己任务太近,他就是异步的了。例如代码:
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
final int[] i = {0,1,2,3,4,5,6,7,8,9,10};
CompletableFuture<Object> voidCompletableFuture = CompletableFuture.completedFuture(1);
System.out.println("-------------------");
Long time = System.currentTimeMillis();
CompletableFuture<Object> helloWorld = CompletableFuture.supplyAsync(() -> {
for (Integer a : i) {
final int finalI = a;
System.out.println(finalI);
writeToFile("hello world", "./src/filetest/file" + finalI + ".txt");
}
return 1;
});
System.out.println("2222222222");
Object o = null;
try {
o = helloWorld.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
System.out.println((System.currentTimeMillis() - time) + "===================");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(o);
System.out.println((System.currentTimeMillis() - time) + "--------------------");
}
private static void writeToFile(String content, String fileName) {
try (FileWriter writer = new FileWriter(fileName)) {
writer.write(content);
} catch (IOException e) {
throw new RuntimeException("Error writing to file: " + fileName, e);
}
}
以上的代码中,get方法就在异步方法之下导致结果
get方法耗时6毫秒
但是如果放的稍微靠后点
如代码:
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
final int[] i = {0,1,2,3,4,5,6,7,8,9,10};
CompletableFuture<Object> voidCompletableFuture = CompletableFuture.completedFuture(1);
System.out.println("-------------------");
Long time = System.currentTimeMillis();
CompletableFuture<Object> helloWorld = CompletableFuture.supplyAsync(() -> {
for (Integer a : i) {
final int finalI = a;
System.out.println(finalI);
writeToFile("hello world", "./src/filetest/file" + finalI + ".txt");
}
return 1;
});
System.out.println("2222222222");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println((System.currentTimeMillis() - time) + "===================");
Object o = null;
try {
o = helloWorld.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
System.out.println(o);
System.out.println((System.currentTimeMillis() - time) + "--------------------");
}
private static void writeToFile(String content, String fileName) {
try (FileWriter writer = new FileWriter(fileName)) {
writer.write(content);
} catch (IOException e) {
throw new RuntimeException("Error writing to file: " + fileName, e);
}
}
此时结果为:
两次打印时间一样,发现,get方法,不耗费时间。
voidCompletableFuture.thenApplyAsync()
thenApplyAsync方法是一个不要求返回值的异步方法。他的使用过程和上面很相似。只是有一个地方需要提示。
这两个方法,都可以异步执行,上面那个有返回值的,你也可以不去拿返回值,你不取他一样的异步执行。但是但是!!,如果你的主线程,当前线程任务都已经走完了,都return了,而且当前线程也不是一直存活的线程池线程,也就是说如果你的主线程死了。那你的这个异步任务就直接被丢弃了!!!!。
以上红色部分是我在main之中的测试。如果你是一个tomcat服务器中的回调任务,tomcat有自己的主循环,所以一般都可以安全执行完毕。