【问题标题】:Will value objects in a copy of a static ConcurrentHashMap reference the same value objects as the original?静态 ConcurrentHashMap 副本中的值对象是否会引用与原始值对象相同的值对象?
【发布时间】:2013-08-31 19:26:48
【问题描述】:

我有一个两部分的问题。

我有: private static ConcurrentHashMap<Integer, Servers> servers= null; 我后来填充。在方法getAllServers 中,我正在这样做:

public static synchronized ConcurrentHashMap<Integer, Server> getAllServers() {
    ConcurrentHashMap<Integer, Server> toReturn = new ConcurrentHashMap<>();
    for(Integer i = 0; i < servers.size(); i ++ ) {
        Server s = servers.get(i);
        if(s.isAlive()) {
            s.incrementConns();
            toReturn.put(i, s);
        }
    }
    return toReturn;
}

问:对s 的修改会反映在servers 中吗?
问:toReturn 会引用与servers 中相同的服务器对象吗?如果是这样,任何创建和修改getAllServers 的返回映射的类是否会修改与servers 相同的对象?

更新:@chrylis: 你指的是哪个Iterator?你能解释一下为什么 for 循环是一个坏主意吗?我在其他领域也使用它:

Iterator itr = servers.entrySet().iterator();
            Map.Entry pair;
            while(itr.hasNext()) {
                pair = (Map.Entry)itr.next();
                Server s= (Server) pair.getValue();
                ...

但我没有发现任何问题,因为我知道servers 将包含具有Integer id 从0 开始的服务器。当我在 for 循环中迭代它们时,顺序对我来说不是问题。

【问题讨论】:

  • 阅读this 开始。 ConcurrentHashMap 并不重要。您需要了解对象引用。
  • 对于初学者来说,你的循环很脆弱;不能保证您的密钥是一组连续的数字,如果有,List 会更有意义。您是否有理由不迭代servers.entrySet()?另外,您在谈论“值对象”,但 s.incrementConns() 听起来像一个突变体。
  • 是的,是的,是的
  • @chrylis:用于服务器对象的键是类中的一个整数参数,该参数在静态 ServerCreator 类中的构造时分配给对象。顺序无关紧要,只要迭代遍历映射的所有值,即服务器对象。是的,incrementConns() 是一个修改对象的另一个参数的 mutator - 在同一个循环中使用 mutator 是个坏主意吗?
  • 迭代器不会遍历所有的值,除非它们在映射的长度上总是,总是,正好是 0 减一。

标签: java static synchronized concurrenthashmap


【解决方案1】:

是的,是的。就这段代码而言,复制Server 对象甚至可能可能。这与ConcurrentHashMap 无关,与Java 中引用的工作方式有关。

【讨论】:

    【解决方案2】:
    1. servers 仅包含对 Server 对象的引用:您对底层对象所做的任何修改都将反映在 servers 中。
    2. Java passes references by value,是的。

    请注意,如果您的代码未正确同步,您可能会在代码中看到陈旧和/或不一致的 Server 对象,但这是另一个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-09
      • 1970-01-01
      相关资源
      最近更新 更多