gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-11-01 03:25:34 27 4
gpt4 key购买 nike

另一个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/

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