MiamiBeach
MiamiBeach

Reputation: 3497

Can Java atomically modify TWO or MORE objects?

Is there a way to modify atomically two or more objects in Java?

For example, atomically set two fields of an object.

UPDATED

I have removed all questions except for the last one due to the rules of the community.

Upvotes: 2

Views: 821

Answers (1)

Dirk
Dirk

Reputation: 31061

As to number 1: No, this is not thread-safe publication. Consider the following interleaving of events:

t1:                   t2:
a = new A();
                      a.getSomeField();
a.setSomeField(1);

in other words, t2 is able to see a partially constructed object, and the value of someField is undefined by the time it is read by t2. Technically, the value, t2 will receive, is undefined, and if you are (un-) lucky, t2 will simply see the default value (in case of an int field usually 0).

For number 2: both threads need to synchronize on the same object, otherwise you can omit the synchronization completely (as it would have the same effect).

Number 3: yes, this is guaranteed by the JVM. All waiting threads will be awaken, and they all will try to grab the lock (again) before they can make progress (and of course, only one can succeed at this, and all other threads will have to implicitly wait -- on the lock, this time, not on the condition variable).

Number 4: There is no "multi-place" compareAndSet. If I need something like this, I usually do it with a tiny helper class:

class State {
    final int field1;
    final String field2;
    State(int f1, String f2) {
        this.field1 = f1;
        this.field2 = f2;
    }
    State derive(int arg1) {
        ...
    }
}

private final AtomicReference<State> state = new AtomicReference<>(new State(0, ""));

public void changeState(int whatever) {

    for (;;) {
        final State s = state.get();
        final State t = s.derive(whatever);
        if (state.compareAndSet(s, t)) return;
    }
}

Upvotes: 3

Related Questions