Java8引入的CompletableFuture
是一个非常非常好用的类库,可以方便的通过它进行多个异步任务的各类花式组合。
关于这个部分,很多博客和文章都有讲到,这篇短文,主要是分别一点:get
和thenAccept
的区别。
class CompleteFutureTest {
@Test
fun test1() {
val completableFuture = CompletableFuture<String>()
val t1=thread(name = "t1") {
completableFuture.get()
println("${Thread.currentThread().name} 中被触发...")
}
thread(name = "t2") {
TimeUnit.SECONDS.sleep(3)
val result = completableFuture.complete("123")
println("${Thread.currentThread().name} 中被赋值...")
}
TimeUnit.SECONDS.sleep(4)
println(t1.isAlive)
}
}
此时结果如下:
t2 中被赋值...
t1 中被触发...
false
因为get
是在t1
中阻塞,所以触发的环境也是t1
@Test
fun test1() {
val completableFuture = CompletableFuture<String>()
val t1=thread(name = "t1") {
val result = completableFuture.thenAccept {
println("${Thread.currentThread().name} 中被触发...")
}
println("${Thread.currentThread().name} 中结束...")
}
thread(name = "t2") {
TimeUnit.SECONDS.sleep(2)
val result = completableFuture.complete("123")
println("${Thread.currentThread().name} 中被赋值...")
}
TimeUnit.SECONDS.sleep(3)
println(t1.isAlive)
}
此时结果如下:
t1 中结束...
t2 中被触发...
t2 中被赋值...
false
从上述结果我们可以发现completableFuture.thenAccept
的如下几个细节:
案例2和案例1给我们带来的启示如下:
thenAccept
不会有线程的上下文切换。get
会在主线程中阻塞。thenAccept
,比如netty
中获取到结果后,通过channel
发送发送消息,用thenAccept
应该比get
更优!