我有番石榴緩存存儲userId互斥緩存。番石榴緩存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;
}
然後我使用帶有互斥對象的synchronized節。我期望來自不同線程的相同用戶將通過同一個密鑰等待另一個任務完成。
比方說,如果我有線程1
synchronized (getMutex(1)) {
}
那麼線程2等待線程1離開同步之前執行完畢,但事實證明,這不會發生,線程不等待對方。
也許我有一個比賽時使用asMap()方法轉換番石榴緩存地圖?
請考慮使用Guava的「Striped」進行鎖定,而不是緩存。 –
@BenManes不適合我。即使我在裏面創建了帶有足夠條紋(鎖)的Striped,當不同的用戶互相等待時,我可能會發生碰撞。 – user12384512
大型懶惰弱條紋是一個弱值地圖。所以,或者直接做同樣的事情,將會是一個更安全的驅逐政策。 –