don*_*ton 11 java singleton multithreading thread-safety multiton
鉴于以下multiton:
public class Multiton
{
private static final Multiton[] instances = new Multiton[...];
private Multiton(...)
{
//...
}
public static Multiton getInstance(int which)
{
if(instances[which] == null)
{
instances[which] = new Multiton(...);
}
return instances[which];
}
}
Run Code Online (Sandbox Code Playgroud)
如果没有getInstance()方法的昂贵同步和双重检查锁定的争议,我们如何保持线程安全和懒惰?这里提到了单身人士的有效方法,但似乎并没有扩展到多人.
ass*_*ias 15
更新:使用Java 8,它可以更简单:
public class Multiton {
private static final ConcurrentMap<String, Multiton> multitons = new ConcurrentHashMap<>();
private final String key;
private Multiton(String key) { this.key = key; }
public static Multiton getInstance(final String key) {
return multitons.computeIfAbsent(key, Multiton::new);
}
}
Run Code Online (Sandbox Code Playgroud)
嗯那很好!
原始答案
这是一个基于JCiP中描述的Memoizer模式的解决方案.它使用ConcurrentHashMap,就像其他答案之一一样,但它不是直接存储Multiton实例,而是可以导致创建未使用的实例,而是存储导致创建Multiton的计算.该附加层解决了未使用实例的问题.
public class Multiton {
private static final ConcurrentMap<Integer, Future<Multiton>> multitons = new ConcurrentHashMap<>();
private static final Callable<Multiton> creator = new Callable<Multiton>() {
public Multiton call() { return new Multiton(); }
};
private Multiton(Strnig key) {}
public static Multiton getInstance(final Integer key) throws InterruptedException, ExecutionException {
Future<Multiton> f = multitons.get(key);
if (f == null) {
FutureTask<Multiton> ft = new FutureTask<>(creator);
f = multitons.putIfAbsent(key, ft);
if (f == null) {
f = ft;
ft.run();
}
}
return f.get();
}
}
Run Code Online (Sandbox Code Playgroud)
这将为您的Multitons提供线程安全存储机制.唯一的缺点是可以创建一个不会在putIfAbsent()调用中使用的Multiton.可能性很小,但确实存在.当然,它发生的可能性很小,但仍然没有造成任何伤害.
从好的方面来说,不需要预分配或初始化,也没有预定义的大小限制.
private static ConcurrentHashMap<Integer, Multiton> instances = new ConcurrentHashMap<Integer, Multiton>();
public static Multiton getInstance(int which)
{
Multiton result = instances.get(which);
if (result == null)
{
Multiton m = new Multiton(...);
result = instances.putIfAbsent(which, m);
if (result == null)
result = m;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2391 次 |
最近记录: |