唯一的方法是使用锁定。您可以通过首先使用检查来最小化这种影响。
if(!map.containsKey("John"))
synchronized(map) {
if(!map.containsKey("John"))
map.put("John", new Person("John"));
}
您需要锁定的原因是您需要在创建 Person 时保留映射,以防止其他线程同时尝试添加相同的对象。ConcurrentMap 不直接支持这样的阻塞操作。
如果您需要最小化锁定到特定键,您可以执行以下操作。
ConcurrentMap<String, AtomicReference<Person>> map = new ConcurrentHashMap<String, AtomicReference<Person>>();
String name = "John";
AtomicReference<Person> personRef = map.get(name);
if (personRef == null)
map.putIfAbsent(name, new AtomicReference<Person>());
personRef = map.get(name);
if (personRef.get() == null)
synchronized (personRef) {
if (personRef.get() == null)
// can take a long time without blocking use of other keys.
personRef.set(new Person(name));
}
Person person = personRef.get();