Блокировка записи в ConcurrentHashMap

214
09 марта 2017, 22:06

Есть ConcurrentHashMap которая имеет следующий вид:

ConcurrentHashMap<Domain, ConcurrentHashMap<Long, ServiceUser>>

В эту мапу пишутся значения из множества потоков, и так как она имеет еще вложеную мапу мне приходится ее создавать один раз в момент когда в определенный Domain ничего не писалось, конкретно в строке

this.userDirectory.put(domain, new ConcurrentHashMap<>());

Проблема заключается в том что два несколько потоков в один и тот же момент пытаются создать ServiceUser в одном и том же Domain и при этом они оба выполняют строку которую я указал выше, получаеться что код который должен был выполниться всего один раз выполняется более двух раз. Проблема решается если сделать этот метод полностью synchronized но тогда получаеться что он будет synchronized всегда, в то время как это нужно всего лишь один раз.

Вовпрос: Каким образом я могу на какое то время заблокировать метод для остальных потоков так что бы не могли выполнить одно и тоже действие не используя synchronized в сигнатуре метода?

Вот исходный код метода:

public void addServiceUser(ServiceUser serviceUser) {
    Domain domain = serviceUser.getDomain();
    if (!this.userDirectory.containsKey(domain)){
        //это место выполняеться дважды
        this.userDirectory.put(domain, new ConcurrentHashMap<>());
    }
    this.userDirectory.get(domain).put(serviceUser.getId(), serviceUser);
}

Пробовал сделать так но не помогло:

public  void addServiceUser(ServiceUser serviceUser) {
    Domain domain = serviceUser.getDomain();
    if (!this.userDirectory.containsKey(domain)){
        ReentrantLock lock = new ReentrantLock();
        lock.lock();
        try {
            this.userDirectory.put(domain, new ConcurrentHashMap<>());
        }finally {
            lock.unlock();
        }
    }
    this.userDirectory.get(domain).put(serviceUser.getId(), serviceUser);
}
READ ALSO
InteliJ IDEA минимальная версия android

InteliJ IDEA минимальная версия android

Как в InteliJ IDEA выбрать минимальную версию андроида в проекте?

248
Методы DAO срабатывают лишь один раз

Методы DAO срабатывают лишь один раз

Внес исправления в предыдущее обращение и сейчас обратил внимание что мои методы работы с ДАО отрабатывают только один разПрошу объяснить...

316
Как через setText присвоить textView число?

Как через setText присвоить textView число?

Необходимо конвертировать его в строку?

251
Java. Крестики нолики

Java. Крестики нолики

Игра крестики ноликиЛишние методы убрал

926