我遇到了使用putIfAbsent的問題,其中第二個線程將在第一個線程完成更新pk值之前嘗試訪問該值。多線程和putIfAbsent競態條件
實施例的代碼。
public <T> Object getLookupValue(final Class<T> type, String key, ConcurrentHashMap<String, T> concurrentMap) {
try {
T value = concurrentMap.get(key);
if (value == null) {
System.out.println("save");
T t = type.getDeclaredConstructor(String.class).newInstance(key);
Object returnedValue = concurrentMap.putIfAbsent(key, t);
if (returnedValue == null) {
System.out.println("session save");
session.save(t);
System.out.println("t ouput " + t.toString());
return t;
}
return concurrentMap.get(key);
} else {
System.out.println("update" + concurrentMap.get(name));
return concurrentMap.get(key);
}
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException ex) {
System.out.println("getLookupValue " + ex);
Logger.getLogger(LineReaderParserImpl.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
輸出
key 2008 thread 1
save
session save
key 2008 thread 0
update Year{name =2008, pk =null}
year pk null thread 0
save
session save
t ouput Year{name =2008, pk =1}
有誰知道爲什麼線程1被線程調用之前完成0加入PK或者爲什麼線程0增加了已經產生的PK前的對象?
我認爲'pk'是在調用'session.save(t)'的過程中分配的? –
@MikeStrobel這是正確的,休眠分配的PK。 –