gpt4 book ai didi

java: volatile数组发布数据变化

转载 作者:行者123 更新时间:2023-11-30 09:41:44 25 4
gpt4 key购买 nike

我有一个复杂的映射,不需要为频繁获取和不频繁更改锁定,因为键唯一地确定其引用元素的行为。

也就是说,如果键是相同的,它所引用的结构将始终具有相同的行为。事实上,键是不可变的 final,引用的值是有效的 final 和/或线程安全的。

假设我在我的自定义 HashMap 中有一个对底层 volatile 引用数组的 volatile 引用。我的这个数组的 hashmap 算法使用 ar.length 成员作为模数,所以如果在 get 函数中,调用者看到一个非当前数组,它的所有引用仍然是好的,并且仍然服从哈希槽,所以如果它在没有互斥量的情况下成功获得非空值,这是正确的。

我的计划是,每当 get 失败时,调用者都会为键构造正确的值,然后执行一个 put,该 put 相对于其他 put 进行锁定,并将一个对象填充到数组中。就在退出临界区之前,put 代码将 volatile 数组字段“ar”重新分配给自身,希望作为给编译器和热点编译器的消息,以创建相对于使用 volatile 数组引用查找散列值的 gets 的栅栏。

只要编译器不 nop "ar = ar"赋值,这就可以工作:

private volatile Object[] ar;

public Object get (Object key)
{
Object[] ar = this.ar;
// get the value from the correct hash slot
}

public synchronized Object put (Object key, Object val) {
{
... stuff a new object into the correct hash slot

ar = ar; // will the compiler truly compile this statement with
// normal volatile fencing relative to the get function??

... if a race condition causes a value to already be mapped, return and use that
... rather than the one we created and passed to put (different than normal put
... contract)
}

最佳答案

无法优化 volatile 写入,所以是的,您将在这里获得内存保证。并且由于从数组中读取值也(至少在概念上)意味着您读取数组的 volatile 变量,因此您也应该获得一个有保证的 volatile 读取。

因此,虽然这应该可行 - 如果您正在使用 Hotspot,通常的方法是使用 sun.misc.Unsafe - 您可以查看 Java5 向上的并发集合,其中该模式是经常证明。 (是的,我们都可以期待在未来获得可变元素数组——afaik Doug Lea 和 Co 正在为此制定规范,但不知道他们有多远。)

虽然问题是为什么你自己实现这个 - Cliff 的非阻塞 hashmap 有一些非常强大的正确性保证(afaik 他们用 CHESS 检查了一个并且很多人已经看过底层状态机)并且性能比较出色从 JDK 到 ConcurrentHashMap。

而且肯定比同步 put 操作更快。

关于java: volatile数组发布数据变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8873170/

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