是否保证 CHM 中的 get 操作能够获得其他线程的 put 正确值?
只要put()
在调用get()
. CHMvolatile
在内部使用访问和其他锁来确保数据同步,不一定是synchronized
关键字。
我问这是因为 get 不同步,除非它看到空值。null 值如何确保其他线程正在更新相同的记录,然后 get 与锁定一起使用?
我假设您指的是这个 javadoc:
因为 value 字段是 volatile 的,而不是 final 的,所以在 Java 内存模型中,非同步读取器在通过数据竞争读取时看到 null 而不是初始值是合法的。尽管导致这种情况的重新排序实际上不太可能发生,但 Segment.readValueUnderLock 方法用作备份,以防在未同步的访问方法中看到空(预初始化)值。
这是试图解释该值不是最终的,因此构造函数中的初始化可以重新排序,并且读者可以看到一个空值。我认为这就是不允许 CHM 存储空值的原因。这允许他们测试 null ,然后在一个synchronized
块内执行另一个 get 。
有关重新排序的构造函数的更多信息,请参阅:实例初始化的重新排序和分配给共享变量的可能吗?
为什么HashEntry
课程是决赛?只是为了确保没有人继承它吗?
是的。这确保了类不能被子类化。这确保了不变性。如果有人对其进行子类化,他们可以更改字段的可见性并破坏并发合同。
使 next [[field]] final 如何有助于获得线程安全?
该next
字段(以及key
andhash
字段)是final
因为这确保了该字段在构造函数中完全初始化。这确实提高了线程安全性,因为优化器无法在构造函数结束后重新排序初始化,并且保证所有线程都能看到数据。
有关该value
字段的信息以及它们如何防止它不被允许覆盖,请参见上文。final
put(...)
为什么Key也是final?(我不确定为什么 Key 在 HashMap 中也是最终的)
与 相同的答案HashEntry
。