重複したイベントを処理しようとしています (MIDI ノートオン信号とノートオフ信号が 3 重になります)。イベントが(ほぼ)同時に発生しない限り、エージェントを使用してロックが機能するようです。
次に例を示します。
(def test-val (agent 0))
(def allow-update (agent true))
(defn increase-val []
(locking allow-update
(when @allow-update
(send allow-update (fn [_ x] x) false)
(send test-val + 1)))
(print @test-val))
(defn run-futures [delay-time]
(send allow-update (fn [_ x] x) true)
(send test-val * 0)
(dotimes [_ 20]
(Thread/sleep delay-time)
(future (increase-val))))
increase-val の呼び出しの間にわずかな遅延を加えてテストすると、次のようになります。
(run-futures 2)
;outputs 0111111111111111111 every time, as expected
しかし、increase-val のすべての呼び出しを一度に発生させると、次のようになります。
(run-futures 0)
;001222222222222222
(run-futures 0)
;000000145555555555
(run-futures 0)
;000000013677777777
ロックをオンにする時間がないように見えるため、エージェントは複数の先物で増加します。
ここで、重複した同時イベントに対処しないようにするための何かが欠けていることを願っています。
ありがとう!