[英]Does Stream.parallel() use a new thread?
所以,我試圖了解Java 8中引入的Stream API。我正在嘗試創建一個可以在單獨的線程上運行的流(僅用於教育目的)
String oracle = "http://www.oracle.com";
URL url = new URL(oracle);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
in.lines().parallel().forEach(System.out::println);
System.out.print("CLOSING THE INPUT STREAM!, shouldnt this crash?");
in.close();
結果不是我所期望的......(我原本期待崩潰,因為我關閉了輸入流,而另一個線程正在讀取它)。 注意.parallel()
方法調用。 相反,代碼似乎以順序方式執行而沒有任何問題。
OUTPUT:
<script language="JavaScript" src="http://www.oracleimg.com/us/assets/metrics/ora_ocom_hp.js"></script>
<!-- End SiteCatalyst code -->
<!-- SS_END_SNIPPET(fragment6,1)-->
<!-- SS_BEGIN_SNIPPET(fragment7,ui)--> <!-- SS_END_SNIPPET(fragment7,ui)-->
</html>
CLOSING THE INPUT STREAM!, shouldnt this crash?
有誰知道發生了什么? 為什么我的代碼沒有崩潰?
並行流確實會嘗試將讀取行的工作分成多個線程。 但是調用本身就是阻塞,即語句等待所有線程完成以繼續下一個語句(關閉輸入流)。
需要注意的一點是, forEach
並不保證並行操作的執行順序與流元素的順序相同,因此在這種情況下,打印的行與原始Web頁面的順序可能不同(請參閱https:// docs .oracle.com / javase / 8 / docs / api / java / util / stream / Stream.html#forEach-java.util.function.Consumer- )。
如果要在后台執行操作而不立即阻止它們的完成,可以使用java.util.concurrent.CompletableFuture.runAsync(Runnable)
和相關方法。 它返回一個CompletableFuture,如果需要可以在以后加入。
如前所述,並行流阻塞當前線程,直到完成所有並行任務。 事實上,當前線程通常也用於執行某些工作,但如果它完成了它的部分,那么它等待其他線程(或竊取他們的一些工作來幫助它們)。
但有一個特殊情況:如果並行流操作拋出異常,那么主線程中的流處理完成(異常),但其他后台線程仍可繼續處理某些輸入塊。 您可以使用以下代碼進行檢查:
// Create list of Strings "0", "1", "2", ..., "99"
List<String> list = IntStream.range(0, 100).mapToObj(String::valueOf)
.collect(Collectors.toCollection(ArrayList::new));
// replace one with non-numeric
list.set(1, "foo");
// Convert every string to number and print it
try {
list.parallelStream().mapToInt(Integer::parseInt).forEach(System.out::println);
} catch (NumberFormatException e) {
// well some non-number encountered
}
System.out.println("Exited");
運行此代碼時,您可能偶爾會看到在"Exited"
消息后打印一些數字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.