java - 是否有可能在 Java 中有效地实现 seqlock?

标签 java optimization concurrency mutex java-memory-model

另一个question让我想知道是否 seqlock可以使用 Java 中的 volatile 版本计数器有效地实现。

这是一个原型(prototype)实现,对于只有一个编写器线程的情况:

class Seqlock {
  private volatile long version = 0;
  private final byte[] data = new byte[10];

  void write(byte[] newData) {
    version++;  // 1
    System.arraycopy(newData, 0, data, 0, data.length);  // 2
    version++;  // 3
  }

  byte[] read() {
    long v1, v2;
    byte[] ret = new byte[data.length];
    do {
      v1 = version; // 4
      System.arraycopy(data, 0, ret, 0, data.length);  // 5
      v2 = version; // 6
    } while (v1 != v2 || (v1 & 1) == 1);
  }
}

基本思想是在写入前后增加版本号,让读者通过验证版本号是否相同且偶数来检查他们是否获得了“一致”读取,因为奇数表示“正在进行写入” .

由于版本是易变的,因此在作者线程和读者线程中的关键操作之间存在各种先行发生关系。

但是,我看不出是什么阻止了 (2) 处的写入移动到 (1) 上方,从而导致读者看到正在进行的写入。

例如,以下 volatile 读写的同步顺序,使用每行旁边注释中的标签(还显示 data 读写,它们不是 volatile 的,因此不属于同步顺序,缩进):

1a (version is now 1)
  2a (not part of the synchronization order)
3 (version is now 2)
4 (read version == 2, happens before 3)
  5 (not part of the synchronization order)
6 (read version == 2, happens before 4 and hence 3)
1b (second write, version is now 3)
  2b (not part of the synchronization order)

ISTM认为5(数据的读取)和2b(数据的第二次写入)之间没有happens-before,所以2b有可能发生在读取之前,读取错误的数据。

如果是这样,将 write() 声明为 synchronized 有帮助吗?

最佳答案

在 java 中,您可以非常简单地实现共享缓冲区(或其他对象):

public class SharedBuffer {

  private volatile byte[] _buf;

  public void write(byte[] buf) {
    _buf = buf;
  }

  public byte[] read() {
    // maybe copy here if you are worried about passing out the internal reference
    return _buf;
  }
}

显然,这不是“seqlock”。

关于java - 是否有可能在 Java 中有效地实现 seqlock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14742808/

相关文章:

java - 发生在 Java 内存模型之前和程序顺序

java - 将摩尔斯电码转换为英语词典单词

java - 如何在android中制作相同大小的所有arraylists

java - 用 Guava 修剪空格分隔的文件

JavaScript:对象键的快速随机索引

java - ConcurrentHashMap put 与 putIfAbsent

java - 如何使用 Java 将文件分成多个部分?

c# - 在内存中固定指针数组

java - 为什么反转循环会使它变慢?

java - ReentrantReadWriteLock(java)-在读取锁内嵌套写入锁