谁可以解释我这个:
final AtomicReference<Integer> atomicReference = new AtomicReference<>(1);
atomicReference.set(2);
Run Code Online (Sandbox Code Playgroud)
在什么意义上最终使用?
什么是 Java 用例AtomicReference#getAndSet?换句话说,是否正确的假设是,如果AtomicReference我在代码中使用的唯一方法是AtomicReference#getAndSet,那么我根本不需要AtomicReference,只需要一个volatile变量就足够了?
例如,如果我有下一个代码:
private final AtomicReference<String> string = new AtomicReference<>("old");
public String getAndSet() {
return string.getAndSet("new");
}
Run Code Online (Sandbox Code Playgroud)
, 是不是总是和
private volatile String string = "old";
public String getAndSet() {
String old = string;
string = "new";
return old;
}
Run Code Online (Sandbox Code Playgroud)
从调用者的角度来看?
在java 17中,AtomicReference有compareAndExchange类似于 的方法compareAndSet,但它不返回布尔值,而是返回原子操作之前的值。我需要它来实现自定义并发结构。
由于项目的限制,我只能使用 Java 8 功能。一些挖掘揭示了VarHandle其中有compareAndExchange。但是,VarHandle需要 Java 9。
因此,看来我必须compareAndExchange亲自实施了。但如何利用现有方法高效地做到这一点呢?(那么compareAndExchangeWeak版本呢?)
(顺便说一句,我不能依赖任何第三方库)
根据文档,我得到了一些关于AtomicReference.compareAndSet()方法的问题,它说:
如果当前值==期望值,则以原子方式将值设置为给定的更新值.
据我所知,==运营商正在比较两个对象的地址,如果是这样,它将如何在这样的例子中起作用
private AtomicReference<AccessStatistics> stats =
new AtomicReference<AccessStatistics>(new AccessStatistics(0, 0));
public void incrementPageCount(boolean wasError) {
AccessStatistics prev, newValue;
do {
prev = stats.get();
int noPages = prev.getNoPages() + 1;
int noErrors = prev.getNoErrors;
if (wasError) {
noErrors++;
}
newValue = new AccessStatistics(noPages, noErrors);
} while (!stats.compareAndSet(prev, newValue));
}
Run Code Online (Sandbox Code Playgroud)
在这段代码片段中,jvm如何知道要在哪些字段中AccessStatistics进行比较compareAndSet()?事实上,我只是想知道这个整个策略是如何工作的,因为java根本不允许覆盖==?谢谢你的评论!
是否AtomicReference.compareAndSet(old,new)保证
old.field 不是变了吗?old不会重新分配给新对象?如果 2 为真,这是否意味着AtomicReference仅对不可变对象有用,例如String?(因为在可变性的情况下old的old.field变化都将丢失与成功 compareAndSet)
AtomicReference 实例使用 Unsafe CAS 操作来利用处理器指令进行锁定。但是我有点困惑它在复杂对象的情况下是如何工作的。
例如,让我们假设我有一个 Person 类的实例(id、firstName、lastName)。我将对象实例共享给多个线程 t1、t2 和 t3。由于操作应该是原子的,所以我不会共享 Person 类对象实例,而是将该对象包装到 AtomicReference 实例中并与所有线程共享。
现在线程 t1 只更新 firstName,线程 t2 只更新 lastName,线程 t3 更新 firstName 和 lastName。之后每个线程都会调用 compareAndSet 方法来反映新的变化。
此外,我正在使用易失性引用,以便写入可以发生在主内存中并对所有线程可见。
我想明白:
在上面的场景中,当 compareAndSet 被调用时,Person 类实例(例如 id、firstName、lastName)的预期值和新值之间将比较哪些内容?
假设线程 t1 更新了 firstName 并调用了 compareAndSet。线程 t2 已更新 lastName 并且将调用 compareAndSet。在这种情况下,AtomicReference 如何保证线程 t2 不会擦除线程 t1 所做的更改,即更新 firstName?
假设 2 个线程 t1 和 t2 同时调用 compareAndSet 那么谁将赢得比赛,而其他失败的线程会怎样?