У меня есть кэш guava с хранилищем userId в кэш-память мьютекса.Guava cache 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. Я ожидаю, что тот же пользователь из разных потоков будет ждать, пока еще одна задача будет завершена одним и тем же ключом.
Скажем, если у меня есть нить 1
synchronized (getMutex(1)) {
}
Затем нить 2 будет ждать потока 1, чтобы оставить синхронизируется до того закончил исполнение, но оказывается, что это не произойдет, нити не ждут друг от друга ,
Возможно, у меня есть гонка при преобразовании кеша guava для сопоставления с использованием метода asMap()?
Рассмотрите возможность использования «Полосатого» Guava для блокировки вместо кеша. –
@BenManes не подходит для меня. Даже если я создаю Striped с достаточным количеством полос (замков) внутри, я могу столкнуться, когда разные пользователи ждут друг друга. – user12384512
Большая ленивая слабая полоса - слабая карта. Таким образом, или, делая то же самое непосредственно, была бы более безопасная политика выселения. –