具有零键功能的线程安全映射

时间:2011-04-18 07:30:04

标签: java synchronization hashmap concurrenthashmap

我需要一个多线程Map对象才能在我的Web服务器缓存中使用,我需要null个密钥。

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

我可以使用任何替代方法,而无需实现某种方式来包装null密钥吗?

2 个答案:

答案 0 :(得分:6)

Collections.synchronizedMap返回的Map支持您提供的Map的所有功能。如果你给它一个HashMap,它支持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);
    }
}

输出:

Size = 1
Size = 2
map.get(null) = b

答案 1 :(得分:2)

据我所知,既没有一种简单的方法可以使ConcurrentHashMap也没有一个同等的类支持null键或值。

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

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

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