我有一个单例模式用来创建对象,目前它的代码如下:
public ApplicationManagerSingleton {
....
private Map<String, Thing> map = new HashMap<String, Thing>();
public Thing getThingById( String id ) {
Thing t = null;
if ( !map.contains(id) ) {
t = longAndCostlyInitializationOfThing();
map.put(id, t );
}
return map.get(id);
}
}
它显而易见的问题是,如果两个线程尝试访问同一件事物,它们可能会复制该事物。
因此我使用了锁:
public ApplicationManagerSingleton {
private Map<String, Thing> map = new HashMap<Sring, Thing>();
public Thing getThingById(String id ) {
synchronized( map ) {
if (!map.contains(id)) {
t = initialize....
}
map.put(id, t);
}
returns map.get(id);
}
}
但现在情况更糟,因为每次创建新资源时,我都会将地图锁定一段时间,这会对想要不同内容的其他线程造成不利影响。
我相信使用Java 5并发包可以更好地解决这个问题。有人能指点我正确的方向吗?
我想避免为其他对不同内容感兴趣的线程锁定类或地图。
putIfAbsent
有助于减少对锁映射的调用。 - John B