问题描述
假设我有两个线程 T1
和 T2
,并且这些线程尝试以随机索引更新数组 A
:
final int[] A = new int[10];
我的问题是:
- 鉴于 32 位字段的存储/加载保证是原子的,我们是否可以假设
A
上的非同步集合(形式为A[x] = random_value
)总是“正确设置”?立> - 如果它们设置正确,我们能保证它们不会改变附近数组索引的值吗?例如,设置
A[3] = 666
是否可以更改A[2]
或A[4]
的值,因为它们很可能位于同一缓存行中? - 如果我们有一个
int
、long
或byte
数组而不是boolean
数组,问题 1. 或 2. 会改变吗?
谢谢
解决方法
根据@apaganin 的评论:
1 和 2。是:
17.6。文字撕裂 Java 虚拟机实现的一个考虑因素是每个字段和数组元素都被认为是不同的;对一个字段或元素的更新不得与任何其他字段或元素的读取或更新交互。尤其是,两个线程分别更新字节数组的相邻元素,不能相互干扰或交互,也不需要同步来保证顺序一致性。
某些处理器不提供写入单个字节的能力。在这样的处理器上通过简单地读取整个字、更新适当的字节,然后将整个字写回内存来实现字节数组更新是非法的。这个问题有时被称为字撕裂,在无法轻易单独更新单个字节的处理器上,将需要一些其他方法。
- 是的。