java hashmap 安全_java-ConcurrentHashMap完全安全吗?

这是线程安全的。 但是,它的线程安全方式可能不是您所期望的。 您可以从中看到一些“提示”:

该类可在程序中与ConcurrentMap完全互操作 依赖于其线程安全性,而不依赖于其同步详细信息

要更完整地了解整个故事,您需要了解ConcurrentMap界面。

原始的ConcurrentMap提供了一些非常基本的读取/更新方法。 甚至我也能够实现ConcurrentHashMap的线程安全实现; 在很多情况下,人们如果不考虑我的同步机制就无法使用我的地图。 这是一个典型的例子:

if (!threadSafeMap.containsKey(key)) {

threadSafeMap.put(key, value);

}

即使地图本身是安全的,这段代码也不是线程安全的。 两个线程同时调用ConcurrentMap,可能会认为没有这样的密钥,因此它们都插入ConcurrentHashMap。

为了解决该问题,我们需要明确地进行额外的同步。 假设我的地图的线程安全性是通过同步关键字实现的,则需要执行以下操作:

synchronized(threadSafeMap) {

if (!threadSafeMap.containsKey(key)) {

threadSafeMap.put(key, value);

}

}

这些额外的代码需要您了解映射的“同步详细信息”。 在上面的示例中,我们需要知道同步是通过“同步”实现的。

ConcurrentMap接口更进一步。 它定义了一些常见的“复杂”操作,涉及对地图的多次访问。 例如,以上示例显示为ConcurrentHashMap。使用这些“复杂”操作,ConcurrentMap(在大多数情况下)的用户无需将操作与对地图的多次访问进行同步。 因此,Map的实现可以执行更复杂的同步机制以获得更好的性能。 ConcurrentHashhMap是一个很好的例子。 实际上,通过为映射的不同分区保留单独的锁来维护线程安全。 它是线程安全的,因为并发访问映射不会破坏内部数据结构,也不会导致任何更新丢失意外等。

考虑到以上所有内容,Javadoc的含义将更加清楚:

“检索操作(包括get)通常不会阻塞”,因为ConcurrentMap的线程安全性未使用“同步”。 ConcurrentHashMap的逻辑本身负责线程安全性。 并且如果您在Javadoc中进一步了解:

该表在内部进行了分区,以尝试允许指定的数字 没有争用的并发更新

检索不仅是非阻塞的,甚至更新也可以同时发生。 但是,非阻塞/并发更新并不意味着它是线程不安全的。 它只是意味着它正在使用简单的“同步”以外的其他方式来确保线程安全。

但是,由于未公开内部同步机制,因此,如果要执行ConcurrentMap提供的操作之外的其他复杂操作,则可能需要考虑更改逻辑或考虑不使用ConcurrentHashMap。例如:

// only remove if both key1 and key2 exists

if (map.containsKey(key1) && map.containsKey(key2)) {

map.remove(key1);

map.remove(key2);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值