【问题标题】:Thread-safe map with null-key capability具有空键功能的线程安全映射
【发布时间】:2011-04-18 07:30:03
【问题描述】:

我需要一个多线程 Map 对象以在我的 Web 服务器的缓存中使用,并且我需要有 null 键。

HashMap 允许我拥有空键,但 ConcurrentHashMap 不允许。我尝试使用Collections.synchronizedMap(new HashMap()) 创建HashMap 的同步版本,但它也不接受null 键。

有没有我可以使用的替代方法,而不必实现某种方式来包装 null 键?

【问题讨论】:

  • HashMap 只允许一个空键。你说的是空值吗?
  • JDK 1.6.0_23, Collections.synchronizedMap(new HashMap()) 可以很好地与 null 键和值配合使用。

标签: java synchronization hashmap concurrenthashmap


【解决方案1】:

Collections.synchronizedMap 返回的Map 支持您给它的Map 的所有功能。如果你给它一个HashMap,它支持null 键(还有null 值,你说“......我需要有“null”键值......”无论哪种方式都可以阅读)。是什么让你认为它没有?

这按预期工作,例如:

import java.util.*;

public class MapTest
{
    public static final void main(String[] args)
    {
        Map map;

        try
        {
            map = Collections.synchronizedMap(new HashMap());
            map.put("one", "a");
            System.out.println("Size = " + map.size());
            map.put(null, "b");
            System.out.println("Size = " + map.size());
            System.out.println("map.get(null) = " + map.get(null));
        }
        catch (Exception ex)
        {
            System.out.println("Exception: " + ex.getMessage());
            ex.printStackTrace(System.out);
        }
        System.exit(0);
    }
}

输出:

大小 = 1
大小 = 2
map.get(null) = b

【讨论】:

  • 对,我的错。我错误地使用 ConcurrentHashMap 进行测试,而不是包装的 HashMap。谢谢。
  • @Iravanchi:哈哈!很容易做到。很高兴有帮助,
  • 这可能不是服务器缓存的好选择。缓存需要具有非常高的性能,即锁定成本可以忽略不计。 ConcurrentHashMap 对此要好得多。如果您想允许空值,您可以通过扩展ConcurrentHashMap 并覆盖put 方法以在给定空值时执行remove 来轻松模拟它,之后该键的get 将返回空值,并且您仍然可以获得更高的并发性能。
  • 请注意,当您迭代返回的集合时,使用此方法必须在返回的地图上同步 - 请参阅 synchronizedMap 上的 javadoc。
【解决方案2】:

据我所知,既没有制作ConcurrentHashMap 的简单方法,也没有支持null 键或值的等效类。

ConcurrentHashMapCollections.synchronizedMap(new HashMap()) 完全不同。

首先因为同步映射会阻止任何并发访问同时发生,即使所有访问都是只读的。 ConcurrentHashMap 不会阻止并发读取访问,在某些情况下,甚至可以接受并发写入。

但更重要的是,如果在使用迭代器时修改了底层映射,则同步映射返回的Iterators 很容易抛出ConcurrentModificationException。另一方面,ConcurrentHashMap 迭代器保证永远不会抛出 ConcurrentModificationException,即使在使用迭代器时更改了底层映射。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    • 2011-03-14
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    相关资源
    最近更新 更多