以下是代码:
HashMap<String, Bean> cachedBean;
public Bean init(String name) {
return new Bean(name);
}
void ServiceHandle(String name) {
if(cachedBean.get(name) == null) {
Bean newBean = init(name);
cachedBean.putIfAbsent(newBean);
}
}
如果1000个客户端使用相同的名称调用ServiceHandle,则将创建1000个bean对象,并且只有其中一个将放入caced地图。有没有办法确保无论同时调用ServiceHandle多少次,都只会创建一个bean。
答案 0 :(得分:2)
嗯,最简单的方法就是制作ServiceHandle
函数synchronized
。那么一次只能有一个线程在内部,因此,每个bean只能创建一个实例。
这很有效,但是当有很多线程要求这些bean时,它们可能成为一个瓶颈:他们最终都会在这个函数的入口处等待对方。
这是避免这种情况的一种方法。它可能看起来有点问题,但我喜欢它的是最常见的路径,在所有内容初始化之后根本不需要任何同步或锁定,并且当初始化bean时,只有线程,要求特定的bean被迫等待,而其他人则不受影响:
class BeanHolder {
// Does not need to be volatile as long as once a bean is initialized it never changes again!
private Bean bean = null;
public Bean getBean(String name) {
if(bean == null) synchronized(this) {
if(bean == null) bean = init(name);
}
return bean;
}
}
ConcurrentHashMap<String, BeanHolder> beans = new ConcurrentHashMap<>();
Bean serviceHandle(String name) {
beans.putIfAbset(name, new BeanHolder());
return beans.get(name).getBean(name);
}