静态同步方法访问静态域

时间:2015-01-21 06:43:32

标签: java multithreading concurrency thread-safety

您好,我有一个实用工具课程。它是一个包含所有静态辅助方法的辅助类。 此类中有一个静态字段。

此类永远不会被实例化。它仅通过静态方法用作帮助程序。

即使这个类永远不会被实例化,我仍然认为为了线程安全,静态方法应该在访问静态字段时同步。我对么?

public class Utils
{
    private static Map<String, String> messagesMap; 

    public static synchronized String getMessage(String key)
    {
        if(messageMap == null) {
            messageMap = new HashMap<String, String>();
            messageMap.put("john", "hello");
            messageMap.put("mary", "hi");
            // actual population of this map comes from a property file.
        }
        return messageMap(key);
    }
}

3 个答案:

答案 0 :(得分:3)

我真的建议你在声明时初始化静态字段(如果它是常量则标记它final)并从你的方法中删除同步。像

这样的东西
private static final String message = "Hello"; // <-- needs a semi-colon.
public static String getMessage() {
    return message;
}

请记住,Java String是不可变的。

对于Map我建议您使用static初始化块(并删除同步并一致地命名变量)。像,

private static Map<String, String> messageMap = new HashMap<>();
static {
    messageMap = new HashMap<String, String>();
    messageMap.put("john", "hello");
    messageMap.put("mary", "hi");
    // actual population of this map comes from a property file.
}

public static String getMessage(String key) {
    return messageMap.get(key);
}

答案 1 :(得分:0)

如果要允许从多个线程访问和修改静态共享状态,是的,您应该使用某种类型的同步。使用synchronized关键字是一种方法。

答案 2 :(得分:0)

如果你确实希望它不应该被实例化,那么在你的类中添加一个私有构造函数。

现在,如果数据字段仅用于参考目的而且永远不会被更改,那么您只需将它们标记为final,而String将完成剩下的工作Immutable

否则,您需要同步方法或代码块,只需确保在访问和修改时使用相同的锁同时进行同步。