[英]CompletableFuture, mutable objects and memory visibility
我試圖了解Java 8中的CompletableFuture
如何與Java內存模型交互。 在我看來,對於程序員的理智,理想情況下應該成立:
CompletableFuture
的線程中的操作發生在執行任何
java.util.concurrent文檔中有一條說明:
在提交之前,操作在一個線程
Runnable
到Executor
發生-before其執行開始。 類似地,Callable
被提交給ExecutorService
。
這表明第一個屬性為true,只要完成將來的線程執行
完成
依賴階段或將其提交給Executor
。 另一方面,在閱讀CompletableFuture文檔后,我不太確定:
為非異步方法的依賴完成提供的動作可以由完成當前
CompletableFuture
的線程執行,或者由完成方法的任何其他調用者執行。
這讓我想到了我的問題:
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
添加到list2
對future
的依賴階段是否可見?
是的,你的兩個假設都是正確的。 原因是, CompletableFuture
中的所有*Async()
方法都將使用java.util.concurrent.Executor
進行異步調用。 如果您不提供,則可以是公共池 ,也可以是為每個任務創建新線程的Executor(如果您將公共池的大小限制為0或1)或用戶提供的Executor。 正如您已經發現的那樣, Executor
的文檔說:
在將Runnable對象提交給Executor之前,線程中的操作發生在執行開始之前,可能在另一個線程中。
因此,在您的示例中,保證"foo"
是lambda中list1
一部分,並且list2
在后續階段中可見。
這基本上由Executor
的文檔涵蓋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.