3

私はJavaでマルチスレッドプログラミングを学んでいます。これが私が得た混乱です。

class Cache<K, V> {
private ConcurrentMap<K, V> cache;
private ConcurrentLinkedQueue<K> lru;

public Cache () {
    // initiate cache and lru
}

public put (K key, V value) {
    // some pre-processing
    synchronized (this) {
        cache.put(key, value);
        lru.add(key);
    }
    // some post-processing
}

}

これは、最近使用されていないレコード (lru) を持つ非常に単純なキャッシュです。明らかに、これら 2 つの操作をアトミックにする必要があります。そうしないと、キャッシュと lru の状態が異なる可能性が非常に高くなります。

ここで、キャッシュを消去するタイマー タスクが必要であるとします。たとえば、キャッシュの半分を消去するとします。私の質問は、上記のコードは、これら 2 つの操作 (キャッシュの書き込みと lru の追加) がクリーン タスクに対してアトミックに見えることを保証するものですか? 以下のようなことはできますか?

class CleanTask {
    Cache cache;   // the reference of Cache
    public void run () {
        // some pre-processing
        for (int i = 0; i < n; i++) {   // Just suppose I need remove n element
            synchronized (XXX) {
                cache.getCache().remove(cache.getLru().poll());
            }
        }
    }
}

XXXには何を入れればいいですか?

どうもありがとう!!!

4

2 に答える 2

2

私の質問は、上記のコードは、これら 2 つの操作 (キャッシュの書き込みと lru の追加) がクリーン タスクに対してアトミックに見えることを保証するものですか?

はい(クリーニングタスクが別のスレッドにあると仮定)

XXXには何を入れればいいですか?

たとえば、同じキャッシュ オブジェクト: synchronized (cache) {a 同期は同じロック (オブジェクト) で発生する必要があります。

あなたの場合に役立つ可能性がある場合は、Java の他のアトミック クラスを調べることもできます:アトミック パッケージ

于 2013-01-02T03:52:14.303 に答える
0

あなたの場合、XXX のキャッシュで同期しますが、代わりにputメソッドとgetLruメソッドを同期することを検討することをお勧めします。

于 2013-01-02T03:52:11.370 に答える