gpt4 book ai didi

java - 数组值更改的线程可见性

转载 作者:行者123 更新时间:2023-11-30 08:16:12 27 4
gpt4 key购买 nike

假设我有以下类(class):

private final int[] ints = new int[5];

public void set(int index, int value) {
ints[index] = value;
}

public int get(int index) {
return ints[index]
}

线程 A 运行以下内容:

set(1, 100);

(非常)在线程 B 运行以下命令后不久:

get(1)

我的理解是,不能保证线程 B 会看到线程 A 所做的更改,因为更改可能仍位于 CPU 缓存/寄存器中......或者可能存在指令重新排序......这是正确的吗?

继续前进,如果我有以下类(class)会发生什么:

public class ImmutableArray {

public final int[] ints

public ImmutableArray(int[] ints) {
this.ints = ints
}
}

使用以下局部变量:

volatile ImmutableArray arr;

线程 A 运行以下命令:

int[] ints = new int[5];
int[0] = 1;

arr = new ImmutableArray(ints);

(非常)在线程 B 运行以下命令后不久:

int i = arr.ints[0];

线程 B 是否由于最终和发生之前的关系而保证获得值 1,即使数组中的值是在此之外设置的?

编辑:在第二个例子中,数组永远不会改变,因此得名“ImmutableArray”

第二次编辑::

所以我对答案的理解是:

int a = 0
volatile int b = 0;

如果线程 A 执行以下操作:

a = 1;
b = 1;

然后线程 B 做了以下事情:

a == 1; // true
b == 1; // true

因此 volatile 充当了一种屏障,但屏障在什么时候结束并允许再次对指令重新排序?

最佳答案

你在这两个方面都是正确的。事实上,即使您放宽了问题陈述,您也是对的。

在第一个示例中,无论线程 B 在多长时间后计算 get(1),都不能保证它会观察到线程 A 调用 set 所写入的值(1, 100)

在第二个例子中,要么 final ints 要么 volatile arr 本身就足以保证观察到 ints[0] = 5。如果没有 volatile,您将无法保证永远观察到 ImmutableArray 实例本身,但无论何时观察它,您都可以保证在完全构建的状态下观察到它。更具体地说,保证与构造函数返回时对象的 final 字段可达到的完整状态有关。

关于java - 数组值更改的线程可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28457601/

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