给定以下多重元素:
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];
}
}
在没有 getInstance() 方法昂贵的同步和双重检查锁定的争议的情况下,我们如何才能保持线程安全和惰性?提到了一种有效的单例方式here但这似乎并没有扩展到 multitons。
最佳答案
更新:使用 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);
}
}
嗯,很好!
原始答案
这是一个基于 the Memoizer pattern as described in JCiP 的解决方案.它像其他答案之一一样使用 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();
}
}
关于java - Java 中的线程安全多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11126866/