我试图从多个线程更新原子(地图)中的嵌套计数器,但会得到不可预测的结果。
var sources = [];
function scheduler(audioStart, index) {
audio = context.createBufferSource();
sources[index] = audio;
audio.buffer = audioSamples[index]; //array with all the loaded audio
audio.connect(context.destination);
audio.start(audioStart + (audio.buffer.duration * index));
}
function stopAll() {
for(let i = 0; i < 8; i++)
if (sources[i])
sources[i].stop(0);
}
我是Clojure的新手,所以我很可能做错了什么,但却无法弄清楚是什么。它打印一个计数器值,结果从4-10变化,每次不同。
我想以原子方式更新计数器值,并希望这种方法总能给出10的计数器值。它只会在失败时重试并最终达到10。
可以同时触发的向上投票功能。
你能看到我在这里做错了吗?
答案 0 :(得分:5)
您正在代码中非原子地更新原子。您首先通过@a
获取其值,然后使用swap
函数应用它。值可能会在两者之间发生变化。
更新值的原子方法是在swap中使用纯函数,而不通过@
引用前一个原子值:
(defn upvote [id]
(swap! a update-in [(keyword id) :counter] inc))