Question

j'ai un cours SomeMutableData avec un public clone() méthode.Je veux m'assurer qu'aucun thread ne voit jamais un état incohérent (en supposant que les instances seront transmises en utilisant uniquement le support).Je suppose que la synchronisation est la possibilité la plus sûre, n'est-ce pas ?

public final class ThreadSafeHolder {
    public ThreadSafeHolder(SomeMutableData data) {
        storeData(data);
    }

    public synchronized SomeMutableData cloneData() {
        return data.clone();
    }
    public synchronized void storeData(SomeMutableData data) {
        this.data = data.clone();
    }

    private SomeMutableData data;
}

Les solutions suivantes sont-elles aussi sûres que la première approche ?

public final class ThreadSafeHolder2 {
    public ThreadSafeHolder2(SomeMutableData data) {
        storeData(data);
    }

    public SomeMutableData cloneData() {
        return data.get().clone();
    }
    public void storeData(SomeMutableData data) {
        this.data.set(data.clone());
    }

    private final AtomicReference<SomeMutableData> data
        = new AtomicReference<SomeMutableData>();
}
Était-ce utile?

La solution

Puisque clone() est beaucoup plus cher que synchronisé, cela n’a guère d’importance du point de vue des performances.

Cependant, le deuxième exemple est aussi thread-safe et légèrement plus rapide.

la seule différence est que le premier exemple vous permet de le faire.(Que cela vous plaise ou non ;)

synchronized(theHolder) {
    SomeMutableData smd = theHolder.cloneData();
    smd.updateIt();
    theHolder.storeData(smd);
}

D'AILLEURS:Je ne pense pas que le support devrait étendre le type qu'il emballe.

MODIFIER:Une méthode plus conviviale pour le GC consiste à utiliser l’approche suivante.vous pouvez écrire copyFrom() de telle sorte qu'aucun objet ne soit créé, que ce soit pour définir ou obtenir les données.

public final class ThreadSafeHolder {
    private final SomeMutableData data = new SomeMutableData();

    public ThreadSafeHolder(SomeMutableData data) {
        copyFrom(data);
    }

    public synchronized void copyTo(SomeMutableData data) {
        data.copyFrom(this.data);
    }

    public synchronized void copyFrom(SomeMutableData data) {
        this.data.copyFrom(data);
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top