7

特定の関数がリクエスト (スレッド) で呼び出された回数を追跡できるようにしたい Web アプリがあります。

ref を使用してスレッド ローカル以外の方法で実行できることはわかっていますが、スレッド ローカルで実行するにはどうすればよいでしょうか。

4

3 に答える 3

12

と呼ばれる便利なツールがありますthread-local。たとえば、 と書くことができます(def counter (thread-local (atom 0)))。これにより、グローバル変数が作成され、derefed のときにスレッドごとに新しいアトムが生成されます。したがって、現在の値を で読み取る@@counterか、 でインクリメントできます(swap! @counter inc)。もちろん、アトム自体を取得して、@counterそれ以降は通常のアトムのように扱うこともできます。

于 2011-09-12T17:38:21.197 に答える
7

binding特別な形式と組み合わせて値にバインドされた動的グローバル変数を使用して、set!その値を変更できます。バインドされた変数bindingはスレッドローカルです。以下は、呼び出し*counter*内で呼び出されるフォームに対して my-fn が呼び出されるたびに増加します。with-counter

(def ^{:dynamic true} *counter*)

(defmacro with-counter [& body]
  `(binding [*counter* 0]
     ~@body
     *counter*))

(defn my-fn []
  (set! *counter* (inc *counter*)))

実証するには、次を試してください。

(with-counter (doall (repeatedly 5 my-fn)))
;; ==> 5

詳細については、http://clojure.org/vars#setを参照してください。

于 2011-09-12T11:50:46.007 に答える
-1

ThreadLocalのインスタンスをref に保持できます。そして、値を増やす必要があるたびに、値を読み取り、値を増やして元に戻します。スレッドは別のリクエストで再利用される可能性があるため、リクエストの開始時にスレッド ローカルを 0 で初期化する必要があります。

于 2011-09-12T11:30:24.067 に答える