When using synchronization, atomic references are not required


Maxim Dmitriev

The code is from the Java Concurrency Guidelines by Fred Long . I understand that a set of atomic operations is not atomic. Therefore, the following code does not meet the requirements. To find the code, see page 23.

public class Adder {

    private AtomicReference<BigInteger> first;
    private AtomicReference<BigInteger> second;

    public Foo(BigInteger f, BigInteger s) {
        first = new AtomicReference<BigInteger>(f);
        second = new AtomicReference<BigInteger>(s);
    }

    public void update(BigInteger f, BigInteger s) {
        first.set(f);
        second.set(s);
    }

    public BigInteger add() {
        return first.get().add(second.get());
    }
}

The correct solution looks like this:

final class Adder {
    // ...
    public synchronized void update(BigInteger f, BigInteger s){
        first.set(f);
        second.set(s);
    }

    public synchronized BigInteger add() {
        return first.get().add(second.get());
    }
}

But I think atomic references in the correct solution are redundant, since synchronizedboth visibility and atomicity are guaranteed.

So my solution looks like this:

public class Addrer {

    private BigInteger first;
    private BigInteger second;

    public Addrer(BigInteger f, BigInteger s) {
        first = f;
        second = s;
    }

    public synchronized void update(BigInteger f, BigInteger s) {
        first = f;
        second = s;
    }

    public synchronized BigInteger add() {
        return first.add(second);
    }
}

am i right?

Piotrique Bezier

You need to make the and firstfields secondprivate and expose the values ​​as synchronized methods. Otherwise, reading the fields directly may result in stale or partially stale BigIntegerobject data (non-volatile field reads are not thread-safe). Then your class will be thread safe.

You might try to make these fields mutable, but there is no guarantee of atomicity for you updateor addthe method , as one thread might update only one field in another thread of you updateor addthe method execution .

public class Adder {
    private BigInteger first;
    private BigInteger second;

    public Adder(BigInteger f, BigInteger s) {
        first = f;
        second = s;
    }

    public synchronized BigInteger getFirst() {
        return first;
    }

    public synchronized BigInteger getSecond() {
        return second;
    }

    public synchronized void update(BigInteger f, BigInteger s) {
        first = f;
        second = s;
    }

    public synchronized BigInteger add() {
        return first.add(second);
    }
}

Related


When using synchronization, atomic references are not required

Maxim Dmitriev The code is from the Java Concurrency Guidelines by Fred Long . I understand that a set of atomic operations is not atomic. Therefore, the following code does not meet the requirements. To find the code, see page 23. public class Adder { pr

With ConcurrentHashMap, when is synchronization required?

For each position: I have a ConcurrentHashMap where I do the following: sequences = new ConcurrentHashMap<Class<?>, AtomicLong>(); if(!sequences.containsKey(table)) { synchronized (sequences) { if(!sequences.containsKey(table)) initial

With ConcurrentHashMap, when is synchronization required?

For each position: I have a ConcurrentHashMap where I do the following: sequences = new ConcurrentHashMap<Class<?>, AtomicLong>(); if(!sequences.containsKey(table)) { synchronized (sequences) { if(!sequences.containsKey(table)) initial

With ConcurrentHashMap, when is synchronization required?

For each position: I have a ConcurrentHashMap where I do the following: sequences = new ConcurrentHashMap<Class<?>, AtomicLong>(); if(!sequences.containsKey(table)) { synchronized (sequences) { if(!sequences.containsKey(table)) initial

atomic_ref when outer underlying type is not aligned as required

Alex Gutenev I read the following on p0019r8 : atomic_ref(T& obj); Requirement : The referenced object must be aligned with required_alignment. If not aligned, cppreference interprets this as UB: The behavior is undefined if obj is not aligned with required_a

atomic_ref when outer underlying type is not aligned as required

Alex Gutenev I read the following on p0019r8 : atomic_ref(T& obj); Requirement : The referenced object must be aligned with required_alignment. If not aligned, cppreference interprets this as UB: The behavior is undefined if obj is not aligned with required_a

atomic_ref when outer underlying type is not aligned as required

Alex Gutenev I read the following on p0019r8 : atomic_ref(T& obj); Requirement : The referenced object must be aligned with required_alignment. If not aligned, cppreference interprets this as UB: The behavior is undefined if obj is not aligned with required_a

atomic_ref when outer underlying type is not aligned as required

Alex Gutenev I read the following on p0019r8 : atomic_ref(T& obj); Requirement : The referenced object must be aligned with required_alignment. If not aligned, cppreference interprets this as UB: The behavior is undefined if obj is not aligned with required_a

atomic_ref when outer underlying type is not aligned as required

Alex Gutenev I read the following on p0019r8 : atomic_ref(T& obj); Requirement : The referenced object must be aligned with required_alignment. If not aligned, cppreference interprets this as UB: The behavior is undefined if obj is not aligned with required_a

atomic_ref when outer underlying type is not aligned as required

Alex Gutenev I read the following on p0019r8 : atomic_ref(T& obj); Requirement : The referenced object must be aligned with required_alignment. If not aligned, cppreference interprets this as UB: The behavior is undefined if obj is not aligned with required_a

atomic_ref when outer underlying type is not aligned as required

Alex Gutenev I read the following on p0019r8 : atomic_ref(T& obj); Requirement : The referenced object must be aligned with required_alignment. If not aligned, cppreference interprets this as UB: The behavior is undefined if obj is not aligned with required_a

atomic_ref when outer underlying type is not aligned as required

Alex Gutenev I read the following on p0019r8 : atomic_ref(T& obj); Requirement : The referenced object must be aligned with required_alignment. If not aligned, cppreference interprets this as UB: The behavior is undefined if obj is not aligned with required_a

Java Volatile, synchronization, atomic example

so what: Hi, I'm reading up on Java concurrency in practice and I read the interesting statement that states Locking guarantees visibility and atomicity. Volatile variables only guarantee visibility. Can any one please explain, if variable declared as volatile

Java Volatile, synchronization, atomic example

so what: Hi, I'm reading up on Java concurrency in practice and I read the interesting statement that states Locking guarantees visibility and atomicity. Volatile variables only guarantee visibility. Can any one please explain, if variable declared as volatile

Java Volatile, synchronization, atomic example

so what: Hi, I'm reading up on Java concurrency in practice and I read the interesting statement that states Locking guarantees visibility and atomicity. Volatile variables only guarantee visibility. Can any one please explain, if variable declared as volatile