agent同期化のサンプル
agentをawait,await-for関数で同期化するサンプルを書いてみた。
send関数によるagentの更新は非同期で行なわれるが、await関数を使い、send関数で指示した関数の実行が完了するまで待機することができる。
待ち時間を指定したい場合はawait-for関数を使用する。
agent-sample.clj
; カウンタを初期値0のagentとして定義 (def counter (agent 0)) ; 1秒待機した後、引数を1増やした値を返す関数 (defn count-fn [x] (Thread/sleep 1000) (inc x)) ; 以下の処理を10回繰り返す。 ; (1)カウンタ値を増やす関数をsend関数で呼び出す。 ; (2)awaitまたはawait-forで(2)のsend関数によるagent更新が完了するまで待機する。 (dotimes [i 10] (send counter count-fn) (await counter) ; (await-for 500 counter) (println (format "@counter=%d" @counter)))
awaitの場合の実行結果
await関数により、カウンタ値の更新が同期化されるため、カウンタ値は1ずつ増える。
user> (load-file "agent-sample.clj") @counter=1 @counter=2 @counter=3 @counter=4 @counter=5 @counter=6 @counter=7 @counter=8 @counter=9 @counter=10 nil user> @counter 10
await-forの場合の実行結果
await-forには500msecを指定しているため、カウンタ値は更新前の値となる。
user> (load-file "agent-sample.clj") @counter=0 @counter=0 @counter=1 @counter=1 @counter=2 @counter=2 @counter=3 @counter=3 @counter=4 @counter=4 nil user> @counter ←5秒ほど待ってから入力 10