考虑一个非常简单的哈希表,具有以下结构:
(defn make-hashtable
[cap]
(let
[tablesize (int (Math/ceil (* cap 1.30)))]
{:tablesize tablesize
:capacity cap
:size (ref 0)
:vector (vec (map (fn [_] (ref '())) (range tablesize)))
:type :hashtable}))
我有基本的操作,例如put
,get
和remove
。我写了一些测试来使用pcalls
并行测试它们。当我第一次开发一个运行在一个“thread
”上的测试时(即只使用一个函数来调用pcalls
)并且它成功了,我必须假设问题不在那里,而在{{1函数不是线程安全的。
删除操作如下:
remove
奇怪的是,它甚至发生了一个只有一个元素的桶没有被删除。这是奇怪的,因为只有向量的元素是refs,而不是整个向量。 问题:为什么这段代码不是线程安全的,我可能做错了什么?
注意:我知道很多人会尝试评论此应用程序的设计,但这是不我感兴趣的答案。我想了解clojure的STM而不是编写纯函数代码。
答案 0 :(得分:0)
您似乎无法在def
块中执行defn
或dosync
,因为它是一个全局副作用,因此会混淆您的交易。虽然我不完全理解,但根据文件不允许副作用,这就是弄乱一切。
感谢Freenode #clojure