gpt4 book ai didi

java - 不可变对象(immutable对象)的同步(在 Java 中)

转载 作者:搜寻专家 更新时间:2023-10-31 08:26:46 25 4
gpt4 key购买 nike

代码片段 - 1

class RequestObject implements Runnable
{
private static Integer nRequests = 0;

@Override
public void run()
{
synchronized (nRequests)
{
nRequests++;
}
}
}

代码片段 - 2

public class Racer implements Runnable
{
public static Boolean won = false;

@Override
public void run()
{
synchronized (won)
{
if (!won)
won = true;
}
}
}

我遇到了第一个代码片段的竞争条件。我 understood这是因为我获得了一个不可变对象(immutable对象)(整数类型)的锁。

我已经编写了第二个代码片段,它再次不受“boolean ”不可变的影响。但这有效(输出运行中不显示竞争条件)。如果我理解了我的 previous question 的解决方案以下是可能出错的一种可能方式

  1. 线程 1 锁定了 won 指向的对象(比如 A)
  2. 线程 2 现在尝试锁定 won 指向的对象并进入 A 的等待队列
  3. 线程 1 进入同步块(synchronized block),验证 A 为假并通过说 won = true(A 认为它赢得了比赛)创建一个新对象(比如 B)。
  4. 'won' 现在指向 B。线程 1 释放对象 A 的锁(won 不再指向)
  5. 现在,在对象 A 的等待队列中的线程 2 被唤醒并获得对对象 A 的锁定,该对象 A 仍然是 false(一成不变)。它现在进入同步块(synchronized block)并假设它也赢了,这是不正确的。

为什么第二个代码片段一直运行良好??

最佳答案

    synchronized (won)
{
if (!won)
won = true;
}

这里有一个您没有注意到的 transient 竞争条件,因为它在第一次执行 run 方法后就消失了。之后,won 变量不断指向表示 true 的同一 Boolean 实例,因此可以正确地用作互斥锁。

这并不是说您应该在实际项目中编写此类代码。所有锁对象都应分配给 final 变量,以确保它们永远不会改变。

关于java - 不可变对象(immutable对象)的同步(在 Java 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18041568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com