簡體   English   中英

CompletableFuture,可變對象和內存可見性

[英]CompletableFuture, mutable objects and memory visibility

我試圖了解Java 8中的CompletableFuture如何與Java內存模型交互。 在我看來,對於程序員的理智,理想情況下應該成立:

  1. 完成CompletableFuture的線程中的操作發生在執行任何 完成 相關的階段之前
  2. 注冊完成 的線程中的操作會在執行 完成 依賴階段之前創建依賴階段

java.util.concurrent文檔中有一條說明:

在提交之前,操作在一個線程RunnableExecutor 發生-before其執行開始。 類似地, Callable被提交給ExecutorService

這表明第一個屬性為true,只要完成將來的線程執行 完成 依賴階段或將其提交給Executor 另一方面,在閱讀CompletableFuture文檔后,我不太確定:

為非異步方法的依賴完成提供的動作可以由完成當前CompletableFuture的線程執行,或者由完成方法的任何其他調用者執行。

這讓我想到了我的問題:

  1. 這兩個假設屬性是否真實?
  2. 在使用CompletableFuture時,是否有任何關於存在或缺乏內存可見性保證的特定文檔?

附錄:

在具體示例中,請考慮以下代碼:

List<String> list1 = new ArrayList<>();
list1.add("foo");

CompletableFuture<List<String>> future =
        CompletableFuture.supplyAsync(() -> {
            List<String> list2 = new ArrayList<>();
            list2.addAll(list1);
            return list2;
        });

是否保證將list1函數可以看到向list1添加"foo" 是否可以保證將list1添加到list2future的依賴階段是否可見?

  1. 是的,你的兩個假設都是正確的。 原因是, CompletableFuture中的所有*Async()方法都將使用java.util.concurrent.Executor進行異步調用。 如果您不提供,則可以是公共池 ,也可以是為每個任務創建新線程的Executor(如果您將公共池的大小限制為0或1)或用戶提供的Executor。 正如您已經發現的那樣, Executor文檔說:

    在將Runnable對象提交給Executor之前,線程中的操作發生在執行開始之前,可能在另一個線程中。

    因此,在您的示例中,保證"foo"是lambda中list1一部分,並且list2在后續階段中可見。

  2. 這基本上由Executor的文檔涵蓋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM