![](/img/trans.png)
[英]Possible improvements in clojure “official” concurrency example (using locks,atoms,stm)
[英]Concurrency with STM in Clojure
我目前正在學習Clojure,並且不確定如何使用STM進行並發。 我要完成的任務非常簡單,我有一個字符串向量,我想同時在每個字符串上運行一個函數,並用函數返回的值替換該字符串。
我目前可以使用pmap輕松完成此操作:
(pmap function string_vector)
如何在Clojure中使用STM做同樣的事情?
STM是一種跨線程共享數據的方式。 如果您根本不需要協調(在此示例中不需要協調),則沒有使用STM的真正理由。
Clojure中的STM是關於隨着時間的推移保持易變事物的狀態。 這些狀態會隨時變化的事物被稱為具有“身份”。 就像您一生都擁有“您”的身份一樣,即使三個月大的“您”可能無法識別120歲的“您”。 因此,讓我們在您的示例中添加一些可變的內容,以便我們有理由使用STM:
讓我們在公共可變的地方存儲字符串,然后在其中並行更改它們:
user> (def current-strings (ref ["a" "b" "c"]))
#'user/current-strings
user> (dosync (alter current-strings (fn [the-string-at-this-instant]
(pmap #(.toUpperCase %) the-string-at-this-instant))))
("A" "B" "C")
user> @current-strings
("A" "B" "C")
user>
在此示例中,我們創建了一個事務,該事務通過向其應用函數來更改字符串集合的狀態。 在內部,該函數恰好並行計算新值。
為了使這一點更有趣,讓我們創建一個可變事物的向量,然后並行更新一堆獨立可變的事物,每個事物在它自己的事務中:
user> (def current-strings [(ref "a") (ref "b") (ref "c")])
#'user/current-strings
user> (doall
(pmap (fn [ref-to-update]
(dosync (alter ref-to-update #(.toUpperCase %))))
current-strings))
("A" "B" "C")
user> (map deref current-strings)
("A" "B" "C")
user>
如您所見,所有這些都不需要STM,因為所有這些操作都可以使用clojure中的其他可變類型來處理,所以原子將是一個不錯的選擇。 和裁判一起玩也很有趣! 玩得開心!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.