简体   繁体   English

ConcurrentHashMap值迭代器可以返回null

[英]ConcurrentHashMap value iterator can it return null

I'm trying to understand the iterator code to ConcurrentHashMap and based on looking at the code it seems that it's possible for the ConcurrentHashMap#values()#iterator to return a null value. 我正在尝试理解ConcurrentHashMap的迭代器代码,并且基于查看代码,似乎ConcurrentHashMap#values()#iterator可能返回null值。

I believe this can happen because, even though you can't add a null value, a call to remove will first mark a value as null. 我相信这可能会发生,因为即使您无法添加空值,对remove的调用也会首先将值标记为null。

Is this true or does the iterator have a way of handling this? 这是真的还是迭代器有办法解决这个问题?

Looking at how get() is implemented, it seems that ConcuurrentHashMap is coded to allow for a situation where the entry value is null due to a class initialization race (which is then handled via a call to Segment.readValueUnderLock() . it appears that the value iterator does not ever check a value entry for null , so it seems you have a valid question (i don't know if there is some other volatile operation which happens during iteration which would alter this possibility). 看看如何实现get() ,似乎ConcuurrentHashMap被编码为允许由于类初始化竞争而导致条目值为null的情况(然后通过调用Segment.readValueUnderLock()来处理它。值迭代器以往任何时候都检查值项null ,这样看来,你有一个有效的问题(我不知道是否有一些其他挥发性操作该迭代过程中会发生哪些会改变这种可能性)。

However, there is this javadoc note on the Segment.readValueUnderLock() method: 但是,在Segment.readValueUnderLock()方法上有这个javadoc注释:

Reads value field of an entry under lock. 读取锁定条目的值字段。 Called if value field ever appears to be null. 如果值字段似乎为空,则调用。 This is possible only if a compiler happens to reorder a HashEntry initialization with its table assignment, which is legal under memory model but is not known to ever occur. 只有当编译器碰巧使用其表分配重新排序HashEntry初始化时才有可能,这在内存模型下是合法的, 但是不知道会发生什么。

(last emphasis mine). (最后强调我的)。

Probably would be a good question for Doug Lea. 对Doug Lea来说可能是一个很好的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM