反思?异步转同步有什么意义
异步转同步有什么意义,直接使用同步方法不好吗?
一直有这个疑问,使用异步转同步就高端,直接使用同步方法一个一个直接就low,一直不理解,难道不是炫技的同时增加代码复杂度吗
后来gpt4给了我答案
使用 CompletableFuture.supplyAsync 提交异步任务然后通过 CompletableFuture.get() 阻塞等待结果,实质上是将一个异步过程转换为了同步操作。这种方式和直接使用同步方法确实在行为上相似,因为调用者都会等待结果完成。但是,它们之间还是有一些差异和潜在的意义:
线程利用:
异步转同步:在异步任务执行的同时,原始线程(通常是主线程或者处理用户请求的线程)可以继续执行其他任务,直到它需要结果并调用 .get() 方法阻塞等待。
直接同步:直接同步方法会阻塞原始线程,直到任务完成才能继续执行其他工作。
异常处理:
异步转同步:CompletableFuture 提供了更丰富的异常处理机制,可以在链式调用中处理异常。
直接同步:异常必须在方法内部或通过传统的 try-catch 块处理。
组合和链式调用:
异步转同步:CompletableFuture 允许你在未来某个时刻获取结果之前,对异步操作进行组合和链式调用,如 thenApply, thenCompose, thenCombine 等。
直接同步:同步方法无法进行类似的链式调用,通常需要在一个同步方法完成后再显式调用另一个方法。
可读性和维护性:
异步转同步:使用 CompletableFuture 可能会使代码结构更清晰,尤其是在处理多个依赖的异步操作时。
直接同步:代码可能更直观,因为它遵循传统的顺序执行模式。
资源管理:
异步转同步:即使是异步转同步,你依然可以控制异步任务的执行(如使用自定义的 Executor),这在直接同步方法中通常不可控。
超时控制:
异步转同步:CompletableFuture.get() 方法允许你设置超时,这样可以避免无限期地等待。
直接同步:实现超时可能需要额外的逻辑。
意义:
尽管异步转同步在行为上与直接同步类似,但它为未来的改进留下了空间。如果将来你决定让原始线程不阻塞,或者需要组合多个异步调用,使用 CompletableFuture 会更加灵活。
总的来说,即使在异步转同步的使用场景中,CompletableFuture 也提供了更多的控制、灵活性和可能的性能优势。然而,如果你不需要这些额外的特性,直接使用同步方法可能会更简单、更直接。
原创:做时间的朋友