java - 同步局部变量

标签 java multithreading java-8 synchronized concurrenthashmap

我注意到ConcurrentHashMap's compute and computeIfAbsent methods中有一个奇怪的结构:

Node<K,V> r = new ReservationNode<K,V>();
synchronized (r) {
  //...
}

考虑到 JIT 很可能将本地对象视为无操作,同步本地对象有何意义?

最佳答案

在代码获取对象的监视器之后,对该对象的引用将存储到 tab 中,它是构成 ConcurrentHashMap 内容的全局可见的节点数组:

Node<K,V> r = new ReservationNode<K,V>();
synchronized (r) {
    if (casTabAt(tab, i, null, r)) {

此时,在同一个 ConcurrentHashMap 上执行其他修改方法的其他线程在遍历全局数组时可能会遇到这个不完整的节点,换句话说,Node 引用已逃逸。

虽然在构造 ReservationNode 时,不可能对新创建的对象进行争用,但在与数组中找到的 Node 进行同步的其他方法中,可能会发生对该 Node 的争用。

这就像“优先级同步”。创建者在引用尚未转义的点进行同步,因此保证成功,而在引用转义的点,所有其他线程将不得不等待,以防万一它们恰好访问该 Node

关于java - 同步局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45977360/

相关文章:

c++ - 如果一个线程在关键部分调用 Acquire(),如果另一个线程调用 Release(),该锁是否会被释放?

C# - System.Windows.Forms.Clipboard.GetDataObject() 没有响应

c# - 窗体关闭时如何停止用户控件上的线程

java - 嵌套的 Java 8 并行 forEach 循环执行不佳。这种行为是预期的吗?

Java 结合自定义比较器使用比较器

java - GridBagLayout 中最轻量级的间隔组件

java - Spring 表单绑定(bind)怎么做呢?无法将类型 [java.lang.String] 的值转换为所需类型

java - 如何从HashMap中获取一些随机键

java - 使用 AssertJ 3 扁平提取 map

java - 如何使一组 jbuttons 在 java 中不可见