繁体   English   中英

Java内存模型是否允许重新排序许多原子/易变量的非同步访问?

[英]Will the Java Memory Model permit the reordering of non-synchronized accesses of many atomic/volatile variables?

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

目的是方法执行ops是下一个:

  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):

当且仅当所有顺序一致的执行没有数据争用时,程序才能正确同步 如果程序正确同步,则程序的所有执行都将显示为顺序一致(第17.4.3节)。

如果所有共享变量都是volatileatomic ,那么就没有数据争用。 这意味着保证了顺序一致性 这意味着,程序的行为中不会出现重新排序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM