是否有必要在`synchronized`之外添加`volatile`关键字以使此类线程安全?

时间:2013-01-25 16:21:11

标签: java multithreading thread-safety volatile synchronized

首先,我有以下(此处已简化)类:

public class MyClass {

    private static Map<String, Object> objects = new HashMap<String, Object>();

    public static Object get(String key) {
        return objects.get(key);
    }

    public static void set(String key, Object object) {
        objects.put(key, object);
    }

}

然后,我想让它成为treahsafe,所以我尝试了synchronized关键字如下:

public class MyClass {

    private static Map<String, Object> objects = new HashMap<String, Object>();

    public static synchronized Object get(String key) {
        return objects.get(key);
    }

    public static synchronized void set(String key, Object object) {
        objects.put(key, object);
    }

}

问题是,synchronized关键字在我的情况下是否足够,或者是否需要添加volatile关键字,即:

public class MyClass {

    private static volatile Map<String, Object> objects = new HashMap<String, Object>();

    public static synchronized Object get(String key) {
        return objects.get(key);
    }

    public static synchronized void set(String key, Object object) {
        objects.put(key, object);
    }

}

3 个答案:

答案 0 :(得分:4)

如果您重新分配objects,那么objects易变只会产生影响。在你的例子中你不这样做它不会有所作为,也没必要。

请注意,最好通过objects最终来强制执行“不可重新分配”。

在您的情况下,您可以简单地使用a thread safe map implementation委派线程安全性(这肯定会比同步实现更好地扩展)。

答案 1 :(得分:3)

volatile并没有神奇地使你的代码线程安全,只是在这里阻止JVM进行在多线程上下文中无关的优化(或者更糟糕的是,阻止你的程序按预期运行)。 / p>

我建议您先查看ConcurrentHashMap,它可能对您的情况有用。

答案 2 :(得分:0)

您没有更改objects中存储的引用,因此使用volatile关键字没有任何价值。