У меня есть ConcurrentHashMap
и метод, который помещает String на карту, затем я выполняю некоторые действия в синхронизированном блоке на основе вставленного значения.
putIfAbsent
возвращает предыдущее значение, связанное с указанным ключом, или null, если для ключа не было сопоставления — на основе официальной документации
Есть 2 действия, которые выполняются в зависимости от того, возвращает ли putIfAbsent
значение null или нет.
Вот в чем хитрость. Я хочу, чтобы первое действие (когда putIfAbsent
возвращает null) выполнялось первым, а все остальные потоки были приостановлены. Мой код работает по назначению в 95% случаев.
private final ConcurrentHashMap<String, String> logins = new ConcurrentHashMap<>();
public void login(String id){
String inserted=logins.putIfAbsent(id,id);
synchronized(logins.get(id)){
if(inserted==null){
System.out.println("First login");
}else{
System.out.println("Second login");
}
}
}
Если я вызываю этот метод с одним и тем же значением String из разных потоков login("some_id");
иногда (около 5% времени), я получаю это сообщение на консоли:
Second login
First login
Что мне нужно изменить, чтобы всегда быть уверенным, что First login
выполняется первым?
Обновление: из того, что я прочитал, возможно ли, что logins.get(id) возвращает null , поэтому синхронизируется с нулевым объектом?
map
бытьlogins
? - person Michael Easter   schedule 14.08.2016