[英]Scala async vs. Java ForkJoinTask
前段時間我發現了Scala異步項目 。 問題是:在這個async
塊中有什么神奇的東西不能通過普通函數實現(沒有宏擴展)?
讓我們看一下介紹中的第一個例子:
import ExecutionContext.Implicits.global
import scala.async.Async.{async, await}
val future = async {
val f1 = async { ...; true }
val f2 = async { ...; 42 }
if (await(f1)) await(f2) else 0
}
我在上面的例子中看不到任何不能用純Java編寫的東西。 這段代碼完全相同:
import java.util.concurrent.*;
import java.util.function.Supplier;
// First define a helper method for creating async blocks:
public static <T> ForkJoinTask<T> async(Supplier<T> supplier) {
return new RecursiveTask<T>() {
@Override
protected T compute() {
return supplier.get();
}
}.fork();
}
ForkJoinTask<Integer> future = ForkJoinPool.commonPool().submit(() -> {
ForkJoinTask<Boolean> f1 = async(() -> true);
ForkJoinTask<Integer> f2 = async(() -> 42);
if (f1.join()) {
return f2.join();
} else {
return 42;
}
});
Scala async
可以做什么,Java不能? 也許在一些更復雜的情況下? 我錯過了什么?
您發布的兩個片段如何在幕后工作中有一個至關重要的區別: 阻止操作 。
scala-async
代碼段大致相當於:
val future = {
val f1 = Future { ...; true }
val f2 = Future { ...; 42 }
f1.flatMap { b =>
if(b) f2 else Future.successful(0)
}
}
這是一個基於回調的代碼。 那里沒有可以阻止任何線程的操作。 只有將來的包裝和回調注冊(在這種情況下發生在flatMap
的引擎蓋下)。 換句話說,一切都是異步的 。
另一方面,Java的fork-join池中的join
方法會阻塞該線程。
沒有阻塞操作是一個重要的性能/可伸縮性優勢,因為 - 極大地簡化 - 無阻塞=>需要更少的線程=>所需的OS資源更少+上下文切換更少。
總結: scala-async
的目的是使非阻塞,基於回調的異步處理在語法中像標准的阻塞方法一樣自然(就像你在Java中使用的那樣)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.