gpt4 book ai didi

java - Java 内存模型是否允许对许多原子/ volatile 变量的非同步访问进行重新排序?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:48:31 26 4
gpt4 key购买 nike

我想知道 JMM 是否允许实现重新排序对 aiada 变量的访问,使其行为不同于代码中显示的意图。

意图是执行操作的方法是下一个:

  1. 获取可变项数组的下一个索引
  2. 在新获得的索引中写入一个数字
  3. 执行自旋锁等待以确保数组的旧索引获得它的值
  4. 打印数组从第一个索引到当前获得的索引的总和。

指数达到 1000 后发生的事情对我来说并不重要。我实际上想将数组用作环,但如果这个问题得到解答,我将能够弄清楚如何去做。

基本上我想避免锁并依赖原子和无锁对象。但是我不知道在这种特定情况下我是否仍然需要隐式同步。

AtomicInteger ai = new AtomicInteger(0);
// let's say all values are null by default
AtomicDoubleArray ada = new AtomicDoubleArray(1000);
int rn = 4; // dice rolled...

void perfomOps(AtomicInteger ai, AtomicDoubleArray ada) {
int i = ai.getAndIncrement();
ada.set(i, rn);
spinlock(ada, i);
printSum(ada, i);
}

void spinlock(AtomicDoubleArray ada, int idx) {
// spinlock in case the other threads couln't write to older indexes yet
if (idx > 0)
for (int c = 0;c < idx; c++)
while (i = ada.get(c) == null);
}

void printSum(AtomicDoubleArray ada, int idx) {
double sum = 0;
for (int i = 0;i < idx; i++)
sum = sum + ada.get(i);
Sytem.out.println(sum);
}

// thread 1
perfomOps(ai, ada); // lets say we get 4 printed

// thread 2
perfomOps(ai, ada); // lets say we get 8 printed

// thread 3
perfomOps(ai, ada); // lets say we get 12 printed

其他线程会继续做同样的事情,可能会出现打印顺序不符合预期的情况,比如 8、12 然后是 4。但是假设下一个线程进入,那么它会看到正确的值并立即正确打印 16 .

所有这些花哨的东西都是为了避免显式锁定以衡量哪个性能更好,无锁版本还是同步版本

最佳答案

Java 内存模型最重要的规则是(§17.4.5):

A program is correctly synchronized if and only if all sequentially consistent executions are free of data races. If a program is correctly synchronized, then all executions of the program will appear to be sequentially consistent (§17.4.3).

如果所有共享变量都是volatileatomic,则不存在数据竞争。这意味着 sequential consistency有保证。这意味着,程序的行为中不会出现可见的重新排序。

关于java - Java 内存模型是否允许对许多原子/ volatile 变量的非同步访问进行重新排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22923370/

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