将代码转换为不可变对象的一般方法是什么?

时间:2018-10-19 14:08:45

标签: java immutability

转换此代码的一般方法是什么?

public class XodusManagerImpl implements XodusManager {

    Map<String, Environment> environmentMap = new LinkedHashMap<>();

    @Override
    public Environment getEnvironment(String xodusRoot, String instance) {
        Environment environment = environmentMap.get(xodusRoot + instance);
        if (environment == null) {
            Environment env = Environments.newInstance(xodusRoot + instance);
            environmentMap.put(xodusRoot + instance, env);
        }
        Environment e = environmentMap.get(xodusRoot + instance);
        return e;
    }

}

放入Immutables,以便此处使用的映射是线程安全的。

1 个答案:

答案 0 :(得分:1)

我也建议使用ConcurrentHashMap,但是如果您真的想在代码中进行操作,则可能会这样做。基本上,如果我们发现需要添加一个新元素,我们将复制旧地图并将新环境添加到其中,然后替换旧环境地图。有些线程可能仍在使用旧的envMap,而有些线程将使用新的envMap。

public class XodusManagerImpl implements XodusManager {

    ImmutableMap<String, Environment> environmentMap = new ImmutableMap.Builder<String, Integer>().build();

    @Override
    public Environment getEnvironment(String xodusRoot, String instance) {
        Environment environment = environmentMap.get(xodusRoot + instance);
        if (environment != null) {
            return environment;
        }
        synchronized(this) {
            environment = environmentMap.get(xodusRoot + instance);
            if(environment==null) {
                Environment env = Environments.newInstance(xodusRoot + instance);
                ImmutableMap<String, Environment> environmentMap = new ImmutableMap.Builder<String, Integer>()
                    .putAll(environmentMap).put(xodusRoot + instance, env).build();
                environmentMap = newEnvironmentMap;
            }
        }
        Environment e = environmentMap.get(xodusRoot + instance);
        return e;
    }

}

编辑:我移动了一些代码,并在同步块中添加了一个检查以确保它尚未添加。