I have some classes that contains both immutable (primitive & references) and mutable data, but mutability come from external writes (another process).
To avoid using synchronized
on every getters/setters (and around the update operation, atomicity is important) or a ReadWriteLock
, I came up with this solution that rely on a volatile
field pointing to a inner class instance:
class A {
private class AData {
final int foo;
AData(X x, ...) {
foo = ...
}
}
private final int a;
private final B b;
private volatile AData data;
A(int a, B b, X x, Y y, ...) {
this.a = a;
this.b = b;
data = new AData(x, y, ...);
...
}
public int getFoo() {
return data.foo;
}
void update(X x, Y y...) {
data = new AData(x, y, ...);
}
}
It looks to me as a good compromise for my use case (a lot more reads, from different threads, than updates), but I'm just trying to make sure I didn't fall into a known anti-pattern.
Best Answer
As far as I understand, you first build a replacement
AData
object, then atomically update the read-accessible reference so that it points to the newly-createdAData
object.The idea looks fine to me, as long as there's no more than writer.
With several writers contending to
.update
, I'd make that methodsynchronized
. This would only affect writers, never readers.