Reputation: 3497
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
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