[英]Difference between Atomic set() and getAndSet() methods in Java
[英]Difference between Atomic set vs volatile set in Java?
說我有以下兩個班級。
public class Foo {
private volatile Integer x = 0;
private volatile boolean istrue = false;
public void setInt(int x) {
this.x = x;
}
public void setBoolean(boolean istrue) {
this.istrue = istrue;
}
public Integer getInt() {
return x;
}
}
VS
public class Bar {
private volatile AtomicInteger x = 0;
private volatile AtomicBoolean istrue = false;
public void setInt(int x) {
this.x.set(x);
}
public void setBoolean(boolean istrue) {
this.istrue.set(istrue);
}
public Integer getInt() {
return this.x.get();
}
}
假設多個線程可以訪問Foo或Bar。 這兩個類是否安全? 這兩個班的真正區別是什么?
在當前示例中,您在方法中有單個賦值語句。 我想你需要提出一個更好的例子。 因為賦值將在單個指令中執行。 這使得兩個實現線程都安全。 即使兩個不同的線程有可能在訪問它們時看到int
不同值,因為到時候,其他線程可能會重置(設置)到不同的值。
看看這個: java中的線程安全是什么?
這兩個類都是編寫的線程安全的。 使用volatile變量和java.util.concurrent.atomic類之間的區別在於原子類允許以原子方式執行更復雜的操作,例如compare和set。 只需直接訪問volatile變量,就可以在compare和set之間進行線程上下文切換,因此在完成set時,不能依賴比較結果仍然有效。
這兩個類都是線程安全的。 但這不是你的問題。
Foo :對字段的讀寫是原子的。 但更復雜的操作,如i ++則不然。 i ++轉換為i = i + 1
,它分解為讀取和寫入,因此在使整個操作不是原子操作之間可能存在線程上下文切換。
Bar :volatile使得對Atomic字段本身的訪問成為原子,因此您可以使用原子方式使用新引用重新分配字段。 但是像compareAndSet
或inc
這樣的字段上的操作是原子的。 問題是,您是否需要對字段進行原子寫入訪問或僅需要操作的原子性? 由於AtomicXXX類型只是值的容器,因此通常不會重新分配變量,而是重新分配原子的值。
所以這應該足夠了:
private final AtomicInteger x = new AtomicInteger(0);
private final AtomicBoolean istrue = new AtomicBoolean(false);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.