簡體   English   中英

功能等效於並發多重映射

[英]Functional equivalent to the concurrent multimap

另一個問題中 ,我詢問了Java的並發多圖。

是否有一些函數式編程(不可變)模式可以在Scala或Clojure程序中使用? 我認為Scala解決方案可能涉及演員和clojure一個atomrefagent ,但可能有更好的方法。 由於兩種語言都允許“回退”到Java互操作並只使用Java解決方案,我可以使用我在第一個問題中得到的任何答案,但這不符合函數式編程范例。 Haskell程序員如何解決這個問題?

標准Clojure映射和集合是不可變的(和持久的)[1],因此它們在並發程序中也能正常工作。 您可能希望將它們存儲在ref / agent / var / atom中,具體取決於您的要求,您可以像以前一樣更新ref / agent / var / atom。

如果值實際為refs,則可以使用更可變的映射,如下所示:

{:a (ref #{1 2 3})
 :b (ref #{4 5 6})}

在這種情況下,您將能夠實際向現有密鑰添加值(當然在事務中)。 添加和刪​​除鍵仍將返回新的地圖,這些地圖將與原始地圖共享相同的引用,因此其他地圖的更改將對其他地方可見:

user=> (def mmap {:a (ref #{1 2 3}) :b (ref #{4 5 6})})
#'user/mmap
user=> mmap
{:a #<Ref@be0446: #{1 2 3}>, :b #<Ref@10aa282: #{4 5 6}>}
user=> (def mmap2 (assoc mmap :c (ref #{7 8 9})))
#'user/mmap2
user=> mmap2
{:c #<Ref@405f6: #{7 8 9}>, :a #<Ref@be0446: #{1 2 3}>, :b #<Ref@10aa282: #{4 5 6}>}
user=> mmap
{:a #<Ref@be0446: #{1 2 3}>, :b #<Ref@10aa282: #{4 5 6}>}
user=> (dosync (alter (:a mmap2) conj 0))
#{0 1 2 3}
user=> mmap
{:a #<Ref@be0446: #{0 1 2 3}>, :b #<Ref@10aa282: #{4 5 6}>}
user=> mmap2
{:c #<Ref@405f6: #{7 8 9}>, :a #<Ref@be0446: #{0 1 2 3}>, :b #<Ref@10aa282: #{4 5 6}>}

[1]也就是說,添加/刪除/修改鍵,值實際上返回一個新地圖,而不更改原始地圖。

功能數據結構是不可變的數據結構。 不可變數據結構沒有並發問題,因為它們無法修改。

暫無
暫無

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

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