代码如下:
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。
最佳答案
嗯,最简单的方法就是使您的 ServiceHandle
函数同步
。那么一次只能有一个线程在里面,因此,每个 bean 只会创建一个实例。
这可行,但可能会成为瓶颈,当有很多线程请求这些 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);
}
关于java - 如何在并发环境中只创建一个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27872357/