更新:使用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);
}
}
嗯,这很好!
原始答案
这是一个基于 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();
}
}