CompletableFuture异步执行
概念
Java 8引入了一个强大的类:CompletableFuture,它在java.util.concurrent包中。CompletableFuture是Future的增强版本,主要用于实现异步编程。
首先,我们要理解什么是Future。Future是Java5引入的一个接口,代表一个异步计算的结果。你可以启动一个计算,获取一个Future对象,然后在计算完成后,通过这个Future对象来获取结果。但Future的功能有限,就是它缺乏机制处理Future的完成事件,我们只能通过Future.get()方法阻塞当前线程来获取结果,这是非常低效的。简单来说,就是使用Future的时候,当执行异步线程的时候,主线程会发生阻塞状态,不能干别的事情。而CompletableFuture是Future的增强版本,就是的当异步线程没有执行完的时候,主线程仍然可以执行其它东西。
使用案例
如下图:
代码如下:
public class Test1 {
public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步执行的线程名字:" + Thread.currentThread().getName());
return "Task result";
});
System.out.println("做其他事情......" + "当前线程:" + Thread.currentThread().getName());
String result2 = future.get(2000, TimeUnit.MILLISECONDS);
System.out.println("Result: " + result2 + " 当前线程" + Thread.currentThread().getName());
String result = future.join();
System.out.println("Result: " + result + " 当前线程" + Thread.currentThread().getName());
}
}
执行结果如下图:
上面可以看出我们使用的是supplyAsync异步线程方法,它是有返回值的;还有一个没有返回值的方法,如下图:
使用案例如下图:
CompletableFuture的complete方法
CompletableFuture类中的complete()方法用于手动完成一个异步任务,并设置其结果。通过调用complete()方法,可以将一个特定的结果设置到CompletableFuture对象中,然后任何等待该异步任务的操作都会得到这个预先设置的结果。如下图:
看下返回结果,如下图:
和预期的结果一样,异步线程里面的代码根本就没有本执行到,因为在异步线程还睡眠的时候,我们就已经给异步线程CompletableFuture调用了complete方法,这个时候异步线程就相当于执行完成了,并且返回complete方法的参数值。
工作场景
那获取角色随机名字脚本举例,它里面是先生成一个CompletableFuture线程,如下图:
看一下getFuture方法的内容,如下图:
现在这个唯一性id就表示一个异步线程CompletableFuture。
然后给服务器发送一个KmlSyncDataAskNotice通知,同时把用到的异步线程对应的futureId传输过去,如下图:
最后会到scene服,如下图:
看下futureCompleted方法,如下图:
最美视角:记住CompletableFuture异步线程在scene服就行了,会先通过askNotice把futureId也就是scene里面对应的异步线程的标志发送给server服,server服获取数据之后,把data和futureId再通过answnerNotice发送给scene服,这样scene服才能通过futureId找到对应的CompletableFuture异步线程,然后调用它的complete方法完成就行了。最后在我们的脚本命令中取出异步线程CompletableFuture中的值。