是否可以有效地在Java中实现seqlock? [英] Is it possible to efficiently implement a seqlock in Java?

查看:186
本文介绍了是否可以有效地在Java中实现seqlock?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

另一个问题让我不知道 seqlock 可以使用Java中的易失性版本计数器有效地实现。

Another question made me wonder if the seqlock can be efficiently implemented with a volatile version counter in Java.

这里是一个原型实现,将只有一个作者线程:

Here's a prototypical implementation, for the case there will only ever be a single writer thread:

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);
  }
}

基本思路是增加版本号并且为了读者检查他们通过验证版本号是相同的甚至,因为奇数表示正在进行中,得到了一致的读取。

The basic idea is to increment the version number before and after writing, and for readers to check they got a "consistent" read by verifying that the version numbers were the same and even, as odd indicates a "write in progress".

因为版本是volatile,所以写线程和读者线程中的关键操作之间存在各种各样的发生前的关系。

There are all sorts of happens-before relationships between the key actions in the writer thread and readers threads since version is volatile.

然而,我不能看到什么阻止在(2)上的写入在(1)之上向上移动,从而使读取器看到正在进行的写入。

I can't, however, see what prevents the write at (2) from moving up above (1) and thus cause a reader to see a write in progress.

例如,以下同步顺序使用每行旁边的注释中的标签(还显示了数据读取和写入,这些读取和写入不是易失性的,因此不是同步顺序的一部分,缩进):

For example, the following synchronization order of volatile reads and writes, using the labels in the comments next to each line (showing also the data reads and writes which are not volatile and thus not part of the synchronization order, indented):

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(数据的第二次写入)之间没有发生之前,因此2b可能在读取之前发生,并且。

ISTM that there is no happens-before between 5 (the read of the data) and 2b (the second write of the data, so it is possible for 2b to occur before the read and wrong data to be read.

如果是这样,请声明 write()同步

If that's true, does declaring write() as synchronized help?

推荐答案

在java中,你可以非常简单地实现一个共享缓冲区:

In java you can implement a shared buffer (or other object) very simply:

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。

obviously, this is not a "seqlock".

这篇关于是否可以有效地在Java中实现seqlock?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆