【问题标题】:java.lang.NegativeArraySizeException with WeakHashMap keySetjava.lang.NegativeArraySizeException with WeakHashMap keySet
【发布时间】:2015-03-31 22:28:35
【问题描述】:

我有以下代码:

 public synchronized static ArrayList<HttpSession> getCurrentSessionList() {
      return new ArrayList<HttpSession>(sessions.keySet());
   }

我们有一个客户正在获取一个java.lang.NegativeArraySizeException,其中列表使用映射sessions 中的键值进行初始化。我无法复制它。他们在 Linux 上使用 OpenJDK 7 build 71。

sessions 是一个 WeakHashMap,我认为这是导致问题的原因。我知道创建新列表会创建对地图中项目的硬引用,但这是短暂的,仅用于报告地图的内容。

创建 ArrayList 的原因是可以循环操作项目等,而不必担心 WeakHashMap 中的项目会消失。

谁能建议一种初始化此列表的安全方法?

【问题讨论】:

  • 你见过这个问题吗? stackoverflow.com/questions/14104897/…
  • 不,我没有......而且我知道这是因为地图同时被修改。我不能用 ConcurrentHashMap 实现替换 WeakHashMap ......我无法从 Java Doc 确定使用 synchronizedMap 是否会停止垃圾收集器的并发修改。
  • 在互联网上搜索 WeakConcurrentHashMap...
  • 你为什么还要拥有WeakHashMap?如果您有会话键入的数据,为什么它不在会话中
  • @EJP,地图是应用程序内所有会话的链接。我们使用它来列出当前登录的用户,并将每个用户名限制为一个并发会话。应用程序使用会话侦听器从该映射中显式添加和删除会话,但它被实现为 WeakHashMap 作为故障保护,如果未显式删除会话,则会话将在销毁时从列表中删除。也许这是过度设计,应该只是一个标准地图,因为我想不出为什么不调用会话侦听器来显式删除它。

标签: java dictionary arraylist


【解决方案1】:

听起来sessions 是由WeakHashMap 支持的同步地图。

JavaDoc for the ArrayList constructor being invoked 说:

构造一个包含指定集合元素的列表,按照集合的迭代器返回的顺序

(添加了重点。)因此,此构造函数迭代给定的集合。

JavaDoc for Collections.synchronizedMap() 包含这个非常重要的说明:

当迭代其任何集合视图时,用户必须在返回的地图上手动同步:

Map m = Collections.synchronizedMap(new HashMap());
    ...
Set s = m.keySet();  // Needn't be in synchronized block
    ...
synchronized (m) {  // Synchronizing on m, not s!
    Iterator i = s.iterator(); // Must be in synchronized block
    while (i.hasNext())
        foo(i.next());
}

不遵循此建议可能会导致不确定的行为。

如果sessions 确实是一个同步映射,那么new ArrayList&lt;HttpSession&gt;(sessions.keySet()) 是不确定的。你需要在sessions上同步:

public synchronized static ArrayList<HttpSession> getCurrentSessionList() {
    final Set<HttpSession> keys = sessions.keySet();
    synchronized (sessions) {
        return new ArrayList<HttpSession>(keys);
    }
}

.. 并且 getCurrentSessionList() 静态方法本身可能不需要同步。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 2017-02-05
    • 2013-08-06
    相关资源
    最近更新 更多