你能做的最好的事情就是让它成为线程安全的,就像javadoc中解释的那样,用 Collections.synchronizedMap(map)
包装它:
请注意,此实现不是同步的。如果多个线程同时访问链接的哈希映射,并且至少有一个线程在结构上修改了映射,则必须在外部同步该映射。这通常是通过对自然封装映射的某些对象进行同步来实现的。如果不存在此类对象,则应使用该方法“包装”映射。这最好在创建时完成,以防止意外地对地图进行不同步访问:Collections.synchronizedMap
Map m = Collections.synchronizedMap(new LinkedHashMap(...));
但是,仅仅让它完全线程安全是不够的,您需要使用包装的映射的实例作为对象的监视器来保护对映射内容的任何迭代:
Map m = Collections.synchronizedMap(map);
...
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());
}
这几乎是您使用我们开箱即用的功能轻松完成的所有操作,如果您想要线程安全且更高效的东西,那么您应该查看Google Guava的Cache
。JDK
下面是一个 LRU
缓存的示例,最大大小为 2
,使用番石榴
构建:
ConcurrentMap<String, String> cache =
CacheBuilder.newBuilder()
.maximumSize(2L)
.<String, String>build().asMap();
cache.put("a", "b");
cache.put("b", "c");
System.out.println(cache);
cache.put("a", "d");
System.out.println(cache);
cache.put("c", "d");
System.out.println(cache);
输出:
{b=c, a=b}
{b=c, a=d}
{c=d, a=d}