簡體   English   中英

java中讀/寫變量的原子操作

[英]Atomic operation on read/write variable in java

我有一個 Java 類,如下所示:

public class Example implements Runnable {

    private int num;

    ...

    // Getter
    public int getNum(){
        return this.num;
    }

    // Setter    
    public void addToNum(int amount) {

        if (this.amount> 0) {
            this.num += amount;
        }
    }

    ...
}

這個類可以被多個線程實例化。 每個實例都有自己的“num”,也就是說,我不希望在它們之間共享“num”變量。

對於每個實例,可以同時訪問多個線程以讀取/寫入 'num' 變量。 那么保護對“num”變量的讀/寫操作以便它們是原子操作的最佳選擇是什么?

我知道在 C# 的情況下,它可以使用 lock(object) 來完成,如下所示,但在 java 中我不知道(我是新手):

C# 上的原子操作

您可以同步這些方法,但您可能會發現使用 AtomicInteger 是一個更快的選擇。

private final AtomicInteger num = new AtomicInteger();

...

// Getter
public int getNum(){
    return this.num.get();
}

// Setter    
public void addToNum(int amount) {
    if (amount > 0) {
        this.num.getAndAdd(amount);
    }
}

這兩種方法都是無鎖的,可以避免暴露可能以意外方式使用的鎖。

在 Java 8 中, getAndAdd使用單個機器代碼指令通過 Unsafe 類進行添加。 AtomicInteger

private volatile int value;

public final int get() {
    return value;
}
public final int getAndAdd(int delta) {
    return unsafe.getAndAddInt(this, valueOffset, delta);
}
public synchronized void addToNum(int amount) {

    if (this.num > 0) {
        this.num += amount;
    }
}

在這里你會找到它的文檔http://www.programcreek.com/2014/02/how-to-make-a-method-thread-safe-in-java/

您可以使用 synchronized ,閱讀它。 您可以同步方法。

在 Java 中,我對使用 volatile 變量表示懷疑,因為 volatile 變量只能在一個線程正在寫入而其他讀取正在讀取時使用。 Volatile 僅在一個線程正在寫入時起作用。

“其中一個線程 (T1) 修改計數器,另一個線程 (T2) 讀取計數器(但從不修改它),聲明計數器變量 volatile 足以保證 T2 寫入計數器變量的可見性。

然而,如果 T1 和 T2 都在增加計數器變量,那么聲明計數器變量 volatile 是不夠的。 稍后再談。”

鏈接: http : //tutorials.jenkov.com/java-concurrency/volatile.html# :~: text=The%20Java%20volatile%20keyword%20is%20intended%20to%20address%20variable%20visibility,read%20directly%20from %20main%20memory

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM