![](/img/trans.png)
[英]How data is stored/accessed and preventing race conditions in maps, java
[英]Race conditions with java references
原子整數,long,boolean等用於對相應類型進行任何原子更新,因為當我們對它們執行任何操作時可能存在競爭條件,例如++。 但是,在可能存在這種競爭條件的情況下,參考的不同案例是什么?
最好的祝福,
凱沙夫
像++
這樣的操作受到競爭條件的影響,因為它們涉及多個謹慎的操作(獲取,增量,存儲)。
設置參考( a = b
)是單個操作,因此不受競爭條件的影響。
對引用類型( a.someMethod()
)的操作可以執行任何他們想要的操作,可能會也可能不會受到競爭條件的影響。
AFAIK引用不受競爭條件的影響,因為JVM保證引用更新是原子操作(不像例如更新long
,其中較低和較高的4個字節在兩個不同的步驟中更新)。 正如SLaks所指出的,唯一的關鍵案例是compareAndSet
,它本質上不是原子的。 這很少用於本機引用,但是當需要一次更新兩個(或更多)邏輯上相關的變量時,它是AtomicReference
的已知習慣用法。 Java Concurrency in Practice ,第15.3.1節為此發布了一個示例,使用AtomicReference
在一個原子操作中更新兩個變量(存儲在一個簡單的類中)。
除了接口的一致性之外, AtomicReference
存在的主要原因是可見性和安全發布 。 從這個意義上說,原子變量是“更好的volatile
”。
出於學習目的,我使用AtomicReference編寫了ConcurrentLinkQueue。
package concurrent.AtomicE;
import java.util.concurrent.atomic.AtomicReference;
public class ConcurrentLinkQueue<V> {
private final AtomicReference<Node> firstNodePointer = new AtomicReference<Node>();
public void fastOffer(final V data){
final Node<V> newNode = new Node<V>(data,Thread.currentThread().getName());
System.out.println(newNode);
AtomicReference<Node> pointer = firstNodePointer;
for(;;){
if(pointer.get() == null){
if(pointer.compareAndSet(null,newNode)){
return;
}
}
pointer = pointer.get().getNext();
}
}
private static class Node<V>{
private AtomicReference<Node> next = new AtomicReference<Node>();
private volatile V data = null;
private String threadName = "";
Node(V data1,String threadName){
this.data = data1;
this.threadName = threadName;
}
@Override
public String toString() {
return "threadName=" + threadName +
", data=" + data;
}
private AtomicReference<Node> getNext() {
return next;
}
private void setNext(AtomicReference<Node> next) {
this.next = next;
}
private V getData() {
return data;
}
private void setData(V data) {
this.data = data;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.