简体   繁体   中英

Atomic operation on read/write variable in java

I have a java class as below:

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;
        }
    }

    ...
}

This class can be instantiated by multiple threads. Each of this instances have its own 'num', that is, I do not want 'num' variable to be shared between all them.

To each instance, multiple threads can be accessed in concurreny in order to read/write 'num' variable. So what is the best option to protect read/write operations on 'num' variable in order to they are atomic operations?

I know that in case on C# it can be done using lock(object) like below link but in java I have no idea (I am new on it):

Atomic operations on C#

You can synchronized the methods, but you might find using AtomicInteger a faster option.

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);
    }
}

Both of these methods are lock-less and avoid exposing a lock which could be used in an unintended way.

In Java 8, the getAndAdd uses a single machine code instruction for the addition via the Unsafe class. From 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;
    }
}

here you'll find documentation for it http://www.programcreek.com/2014/02/how-to-make-a-method-thread-safe-in-java/

You can use synchronized , read about it. You can synchronized methods.

In Java ,I doubt about using volatile variables because volatile variables can used only when one thread is writing and other reads are reading. Volatile works only when one thread is writing .

"where one thread (T1) modifies the counter, and another thread (T2) reads the counter (but never modifies it), declaring the counter variable volatile is enough to guarantee visibility for T2 of writes to the counter variable.

If, however, both T1 and T2 were incrementing the counter variable, then declaring the counter variable volatile would not have been enough. More on that later."

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM