Uso delle classi interne per ottenere comportamenti thread-safe senza sincronizzazione

1

Ho alcune classi che contengono dati sia immutabili (primitivi e di riferimento) che mutabili, ma la mutabilità proviene da scritture esterne (un altro processo).

Per evitare di usare synchronized su ogni getter / setter (e attorno all'operazione di aggiornamento, l'atomicità è importante) o un ReadWriteLock , ho trovato questa soluzione che si basa su un campo volatile che punta a una classe interna esempio:

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, ...);
   }

}

Mi sembra un buon compromesso per il mio caso d'uso (molte più letture, da thread diversi, rispetto agli aggiornamenti), ma sto solo cercando di assicurarmi di non cadere in un anti-pattern noto.

    
posta Rhangaun 22.03.2018 - 19:01
fonte

1 risposta

1

Per quanto ho capito, per prima cosa costruisci un oggetto sostitutivo AData , quindi aggiorna atomicamente il riferimento accessibile in lettura in modo che punti all'oggetto AData appena creato.

L'idea mi sembra a posto, purché non ci sia altro che scrittore.

Con diversi scrittori che si contendono di .update , realizzerei quel metodo synchronized . Ciò interesserebbe solo gli scrittori, mai i lettori.

    
risposta data 22.03.2018 - 21:01
fonte