我阅读了有关ConcurrentHashMap的JDK源代码。
但是以下代码使我感到困惑:
public boolean isEmpty() {
final Segment<K,V>[] segments = this.segments;
...
}
我的问题是:
声明为“this.segments”:
final Segment<K,V>[] segments;
因此,这里在方法的开头,声明了相同的类型引用,指向了相同的内存。
作者为什么要这样写?他们为什么不直接使用this.segments?有什么原因吗?
最佳答案
这是涉及volatile
变量的无锁代码的典型用法。在第一行中,您一次读取了volatile
,然后使用它。同时,另一个线程可以更新volatile
,但是您仅对最初读取的值感兴趣。
同样,即使所讨论的成员变量不是volatile,而是最终变量,该习惯用法也与CPU缓存有关,因为从堆栈位置进行读取比从随机堆位置进行读取更易于缓存。本地var最终绑定(bind)到CPU寄存器的机会也更高。
对于后一种情况,实际上存在一些争议,因为JIT编译器通常会解决这些问题,但是Doug Lea是坚持一般原则的人之一。