3

とのソースコードを比較すると、clojure.lang.Refどちらも。clojure.lang.Atomから継承していることがわかりclojure.lang.ARefます。

clojure.lang.ARefには、notifyWatchesすべてのウォッチ機能に変更が加えられたことを知らせる機能があります。

swap!とは、その実装の呼び出しでreset!機能します。clojure.lang.AtomnotifyWatches

例えば。

public Object swap(IFn f) {
for(; ;)
    {
    Object v = deref();
    Object newv = f.invoke(v);
    validate(newv);
    if(state.compareAndSet(v, newv))
        {
        notifyWatches(v, newv);
        return newv;
        }
    }
 }

ただし、で検索しnotifyWatchesclojure.lang.Refも何も表示されません。関数は次のalterようになります。

public Object alter(IFn fn, ISeq args) {
   LockingTransaction t = LockingTransaction.getEx();
   return t.doSet(this, fn.applyTo(RT.cons(t.doGet(this), args)));
}

どのメソッドもnotifyWatchesを呼び出していない場合、refのすべてのウォッチ関数はどのように通知されますか?

4

2 に答える 2

3

notifyWatches探している呼び出しは、クラスのrunメソッドで発生します。LockingTransaction

参照の変更はトランザクションで発生します。doSetのメソッドへの呼び出しLockingTransactionが渡されることに注意してくださいthis(参照への参照)。トランザクション内で適用される変更はメソッドによって確立されますdoSetその変更はのrunメソッド内で有効になりますLockingTransaction。トランザクションが正常に実行さnotifyWatchesれると、によって記録されたRefへの参照を使用して呼び出されdoSetます。

于 2012-11-14T12:59:13.193 に答える
2

clojure.lang.Refclojure.lang.ARefを拡張します。clojure.lang.ARefはウォッチを持ち、notifyWatchesメソッドを提供します

于 2012-11-14T01:34:45.997 に答える