简体   繁体   English

为什么ConcurrentHashMap中的HashEntry是最终版本?

[英]Why is HashEntry in ConcurrentHashMap final?

I am going through source code of ConcurrentHashMap in jdk 7 and have few questions. 我正在jdk 7中浏览ConcurrentHashMap源代码,并且有几个问题。 I have already gone through all the questions on CHM on StackOverFlow, but could not find the answer. 我已经在StackOverFlow上解决了关于CHM的所有问题,但是找不到答案。

  1. Is get() operation in CHM guaranteed to get correct value of put() by other thread? CHM中的get()操作是否get()保证通过其他线程获得正确的put()值? I am asking this as get is not synchronized unless it sees the null value. 我问这是因为get不synchronized除非它看到null值。 How null value ensures that same record is being updated by other thread and then get is used with lock? 空值如何确保同一记录被其他线程更新,然后将get与锁一起使用?

  2. This is related to HashEntry static class where key and values are stored. 这与存储键和值的HashEntry静态类有关。

    a. 一种。 Why is this class final? 为什么这堂课是决赛? Is it just to make sure nobody subclasses it? 只是为了确保没有人继承它吗? What happens if somebody subclasses it -- is something wrong with that? 如果有人将其子类化怎么办-这有问题吗?

    b. How does making the next field final helps in getting thread safety? 使下一个字段最终决赛如何帮助获得线程安全?

    c. C。 Why is Key also final? 为什么Key也是最终的? (I am not sure why Key is final in HashMap also) (我不确定为什么Key在HashMap也是最终的)

Is get operation in CHM guaranteed to get correct value of put by other thread? CHM中的get操作是否可以确保获得其他线程的正确放置值?

It certainly is guaranteed as long as the put() has completed before the call to get() . 只要在调用get()之前put()已经完成,就肯定可以保证。 CHM uses volatile accesses and other locks internally to ensure the data is synchronized, not necessarily the synchronized keyword. CHM在内部使用volatile访问和其他锁​​定来确保数据同步,而不必确保synchronized关键字。

I am asking this as get is not synchronized unless it sees the null value. 我问这是因为get不同步,除非它看到null值。 How null value ensures that same record is being updated by other thread and then get is used with lock? 空值如何确保同一记录被其他线程更新,然后将get与锁一起使用?

I assume you are referring to this javadoc: 我假设您是指这个javadoc:

Because the value field is volatile, not final, it is legal wrt the Java Memory Model for an unsynchronized reader to see null instead of initial value when read via a data race. 由于值字段是易失性的,而不是最终值,因此对于Java内存模型而言,对于非同步读取器而言,通过数据竞争读取空值而不是初始值是合法的。 Although a reordering leading to this is not likely to ever actually occur, the Segment.readValueUnderLock method is used as a backup in case a null (pre-initialized) value is ever seen in an unsynchronized access method. 尽管实际上不太可能导致重新排序,但是如果在非同步访问方法中看到空值(预初始化),则可以使用Segment.readValueUnderLock方法作为备份。

This is trying to explain that the value is not final so therefore the initialization in the constructor could be reordered and a reader could see a null value. 这试图说明该值不是最终值,因此可以对构造函数中的初始化进行重新排序,并且读者可以看到一个空值。 I assume this is why CHM is not allowed to store null values. 我认为这就是为什么不允许CHM存储空值的原因。 That allows them to test for null and then do another get inside a synchronized block. 这样一来,他们就可以测试是否为null,然后在synchronized块中进行另一个获取。

For more information around constructor reordered, see: Is reordering of instance initialization and assignment to a shared variable possible? 有关重新构造构造函数的更多信息,请参见: 是否可以对实例初始化和对共享变量进行重新排序?

Why is the HashEntry class final? 为什么HashEntry类为期末HashEntry Is it just to make sure nobody subclasses it ? 只是为了确保没有人继承它吗?

Yes. 是。 This ensures that the class cannot be subclassed. 这确保了该类不能被子类化。 This ensures immutability. 这确保了不变性。 If someone subclassed it, they could change the visibility of the fields and break the concurrency contract. 如果有人将其分类,则他们可以更改字段的可见性并破坏并发合同。

How does making next [[field]] final helps in getting thread safety? 进行下一个[[field]]的最终结果如何有助于提高线程安全性?

The next field (as well as the key and hash fields) is final because this ensures that the field is fully initialized in the constructor. next字段(以及key字段和hash字段)是final因为这确保了该字段在构造函数中已完全初始化。 This does improve thread safety since the initialization cannot then be reordered past the end of the constructor by the optimizer and all threads are guaranteed to see the data. 这确实提高了线程安全性,因为优化器无法在构造函数的末尾对初始化进行重新排序,并且保证所有线程都能看到数据。

See above for information about the value field and how they protect against it not being final which allows put(...) to overwrite. 请参阅上面的内容,以获取有关value字段以及如何防止它不是 final (允许put(...)覆盖)的信息。

Why is Key also final? 为什么Key也是最终的? (I am not sure why Key is final in HashMap also) (我不确定为什么Key在HashMap中也是最终的)

Same answer as the HashEntry . HashEntry答案相同。

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

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