私はグアバキャッシュに、ストアのユーザーIDをミューテックスキャッシュに持っています。グアバキャッシュasMapメソッド
Cache<Long, Object> byUserIdMutex = CacheBuilder.newBuilder()
.concurrencyLevel(4)
.weakKeys()
.maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
private Object getMutex(long userId) {
Object newLock = new Object();
Object old = byUserIdMutex.asMap().putIfAbsent(userId, newLock);
if (old != null) {
return old;
}
return newLock;
}
次に、mutexオブジェクトとsynchronizedセクションを使用しています。私は、異なるスレッドからの同じユーザーが、同じキーで別のタスクを完了するのを待つことを期待しています。
私は、スレッド1
synchronized (getMutex(1)) {
}
を持っている場合は、スレッド2が完成し、実行する前に同期残すために、スレッド1を待つことになるが、それはそれは起こらないことが判明し、スレッドがお互いを待っていないのは、言ってみましょう。
グアバキャッシュをasMap()メソッドを使用してマップすると、私はレースをしたことがありますか?
代わりに、キャッシュの代わりにGuavaのロック用に「Striped」を使用することを検討してください。 –
@BenManesは私には合いません。内部に十分なストライプ(ロック)が付いたStripedを作成しても、別のユーザーがお互いを待っているときに衝突する可能性があります。 – user12384512
大きな怠惰な弱いストライプは弱い価値のあるマップです。そうすること、または同じことを直接行うことは、より安全な追放政策になります。 –