gpt4 book ai didi

java - 再次设置 AtomicBoolean

转载 作者:搜寻专家 更新时间:2023-11-01 02:35:49 38 4
gpt4 key购买 nike

我正在使用 AtomicBoolean 来强制执行线程之间的 volatile 可见性。一个线程正在更新值,另一个线程只读取它。

假设当前值为 true。现在假设一个写线程再次将其值设置为true:

final AtomicBoolean b = new AtomicBoolean(); // shared between threads

b.set(true);
// ... some time later
b.set(true);

在这个“虚拟”set(true) 之后,当读取线程 调用get() 时是否有性能损失? 读取线程是否必须重新读取并缓存该值?

如果是这种情况,写入线程 可以完成:

b.compareAndSet(false, true);

这样,读取线程只需为真正的变化而失效。

最佳答案

compareAndSet() :

public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}

compareAndSwapInt() 已经是原生的了:

UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
UnsafeWrapper("Unsafe_CompareAndSwapInt");
oop p = JNIHandles::resolve(obj);
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END

其中 Atomic::cmpxchg 是 JVM 执行开始时某处的 generated

  address generate_atomic_cmpxchg() {
StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg");
address start = __ pc();

__ movl(rax, c_rarg2);
if ( os::is_MP() ) __ lock();
__ cmpxchgl(c_rarg0, Address(c_rarg1, 0));
__ ret(0);

return start;
}

cmpxchgl() 生成 x86 代码(它也有更长的遗留代码路径,所以我不在这里复制那个):

 InstructionMark im(this);
prefix(adr, reg);
emit_byte(0x0F);
emit_byte(0xB1);
emit_operand(reg, adr);

0F B1 实际上是一个 CMPXCHG 操作。如果你检查上面的代码,if ( os::is_MP() ) __ lock(); 在多处理器机器上发出一个 LOCK 前缀(让我跳过引用 lock() ,它发出一个 F0 字节),所以几乎无处不在。

正如 CMPXCHG 文档所说:

This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically. To simplify the interface to the processor’s bus, the destination operand receives a write cycle without regard to the result of the comparison. The destination operand is written back if the comparison fails; otherwise, the source operand is written into the destination. (The processor never produces a locked read without also producing a locked write.)

因此,在多处理器 x86 机器上,NOP-CAS 也会进行写入操作,从而影响缓存行。 (重点是我加的)

关于java - 再次设置 AtomicBoolean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53434995/

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