java - Java 中的线程安全多线程

标签 java multithreading thread-safety singleton 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];
    }
}

在没有 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/

相关文章:

c++ - 在 GCC 中关闭 COW

java - hibernate + Spring 启动2 : Not checking the default schema

java - 如何获取Arraylist java中真值的数量

java - 如何在android中使用GSON创建JSONArray

c - 在队列的关键部分使用二进制信号量而不是互斥锁进行互斥有什么好处吗?

c# - 如果我调用 C# 事件处理程序并调用它,会发生什么情况?

java - 测试java中看不见的字符

c++ - 如何创建支持 `<<` 操作的线程安全日志类?

C++ std::lock 和 std::unique_lock 有什么区别?

java - Shiro 的 DefaultPasswordService 线程安全吗?