Selon Java Concurrency in Action, si nous avons la classe suivante :
public class Wrapper {
private int num;
public Wrapper(int num) {
this.num = num;
}
public void assertCorrectness() {
if (num != num)
throw new AssertionError("This is false");
}
}
et que nous initialisons une instance de cette classe et la publions d'une manière non sécurisée (par le biais d'un simple champ public par exemple), alors la fonction assertCorrectness() pourrait effectivement lancer une AssertionError, si elle est appelée depuis un autre thread. En d'autres termes, cela signifie qu'un autre thread pourrait voir une référence à jour à l'instance, mais l'état de l'instance elle-même pourrait être obsolète (ainsi un thread peut voir qu'un objet existe mais qu'il est dans un état partiellement construit / inconsistant).
D'autre part, il est dit que la publication d'une instance de cette classe par le biais d'une référence volatile est considérée comme sûre. Cependant, j'ai cru comprendre que volatile garantit simplement que chaque thread verra toujours une version à jour d'une référence, mais pas l'état de l'objet référencé. Nous pouvons donc être sûrs que si un thread attribue une nouvelle instance de la classe Wrapper à un champ volatile, tous les autres threads verront que la référence a été mise à jour. Mais y a-t-il un risque qu'ils voient toujours un objet dans un état incohérent / partiellement construit ?