有以下两个实现功能的方法public String getName(){ // 模拟功能的耗时操作 try { Thread.sleep(2000); // 模拟耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } return csdn:sorako; } public String getCover(){ // 模拟功能的耗时操作 try { Thread.sleep(2000); // 模拟耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } return cover; }有一个需求需要异步调用获得结果之后在执行数据库Mapper插入数据库操作用打印表示一、异步调用一个方法如果是如下写法FileInfo fileInfo new FileInfo(); CompletableFutureString future CompletableFuture.supplyAsync(() - getName()); future.thenAccept(name - fileInfo.setFileName(name)).exceptionally(ex - { log.error(异步执行失败); return null; }); //执行Mapper。。。。。。。。。。 System.out.println(fileInfo fileInfo);答案是mapper执行sql后插入数据库的数据为空在异步调用时会直接执行主线程的后续部分没有等异步执行返回结果就直接执行mapper中的操作了。所以可以把mapper操作放到回调函数中执行FileInfo fileInfo new FileInfo(); CompletableFutureString future CompletableFuture.supplyAsync(() - getName()); future.thenAccept(name - { fileInfo.setFileName(name); //执行Mapper。。。。。。。。。。 System.out.println(fileInfo fileInfo); }).exceptionally(ex - { log.error(异步执行失败); return null; });但是执行会发现控制条没有任何信息因为主线程已经结束了异步调用还没走到mapper操作打印那里但是如果在主线程还没结束是会打印出来信息的。我们让主线程暂停几秒模拟一些后续操作。结果如下但是事实上我们无法预测是否主线程后续操作的结束时间前异步调用能执行所以我们可以让主线程必须在异步调用返回结果后在执行FileInfo fileInfo new FileInfo(); CompletableFutureString future CompletableFuture.supplyAsync(() - getName()); future.thenAccept(name - { fileInfo.setFileName(name); //执行Mapper。。。。。。。。。。 System.out.println(fileInfo fileInfo); }).exceptionally(ex - { log.error(异步执行失败); return null; }); // 等待异步任务完成 try { future.get(); // 或者 future.join(); } catch (Exception e) { log.error(等待异步任务时发生错误: e.getMessage()); }也可以简化在这里.get()会等待异步调用完成,但是也会可能抛出异常,需要抛出捕获,我们可以用.join()代替这两个的区别AI生成future.get() 和 future.join() 都是用于处理并发编程中异步任务的结果但它们属于不同的编程框架或库并且具有不同的用途和行为。### future.get()- **库**: Java 的 java.util.concurrent.Future 接口。- **用途**: 用于获取异步计算的结果。- **行为**:- 调用 future.get() 会阻塞调用线程直到异步任务完成并返回结果。- 如果任务尚未完成调用线程会被挂起直到任务完成。- 如果任务执行过程中抛出异常future.get() 会将异常重新抛出。- **示例**:Future future executorService.submit(() - {// 模拟一个异步任务Thread.sleep(2000);return 123;});try {Integer result future.get(); // 这会阻塞直到任务完成System.out.println(Result: result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}### future.join()- **库**: Java 的 Thread 类或 Kotlin 的协程join() 在 Kotlin 协程中表现为 await()。- **用途**: 用于等待一个线程或协程完成。- **行为**:- 在 Java 中thread.join() 会使当前线程调用 join() 的线程等待直到目标线程终止。- **示例**:Thread thread new Thread(() - {// 模拟一个任务try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(“Thread finished”);});thread.start();try {thread.join(); // 这会阻塞直到线程完成} catch (InterruptedException e) {e.printStackTrace();}System.out.println(“Main thread continues”);### 总结- future.get() 是 Java 并发库中的方法用于获取异步任务的结果并阻塞调用线程直到任务完成。- join() 是 Java 线程的方法用于等待一个线程完成。它们虽然都涉及到等待某个任务完成但应用场景和所属的库不同。但是有人就会问了在这里等待异步调用完成再执行后续操作那不如不使用异步操作好像确实是这样那假如是执行两个异步操作呢二、异步调用两个方法异步调用执行两个方法FileInfo fileInfo new FileInfo(); CompletableFutureString future1 CompletableFuture.supplyAsync(() - getName()); CompletableFutureString future2 CompletableFuture.supplyAsync(() - getCover()); // 使用allOf等待所有Future完成 CompletableFutureVoid allFutures CompletableFuture.allOf(future1, future2); // 注册回调当所有Future都完成时执行 allFutures.thenRun(() - { try { String fileName future1.get(); String fileCover future2.get(); fileInfo.setFileName(fileName); fileInfo.setFileCover(fileCover); //执行Mapper。。。。。。。。。。 System.out.println(fileInfo fileInfo); } catch (Exception e) { log.error(异步执行失败); } }).exceptionally(ex - { ex.printStackTrace(); return null; }).join();当然还是用使用.join()或者.get()保证异步调用执行完这里我们可以看出执行时间2s.24ms那如果不使用异步调用呢执行时间4s.35ms可以看出在多个异步调用执行复杂操作时效率是更高的。当然这里的前提都是主程序的后续执行需要异步调用后返回执行结果如果不需要异步调用的返回结果。那首选异步操作。