Java – Using inner classes to achieve thread-safe behavior without synchronization

anti-patternsclass-designjavamultithreadingsynchronization

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-created AData 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 method synchronized. This would only affect writers, never readers.

Related Topic