34 votes

Pourquoi AtomicBoolean ne peut-il pas remplacer Boolean?

L'Oracle JDK Javadoc pour AtomicBoolean états:

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicBoolean.html

Une valeur booléenne qui peut être mis à jour automatiquement. Voir la java.util.de façon concomitante.atomique de spécification de paquetage pour la description de les propriétés de l'atome variables. Un AtomicBoolean est utilisé dans des applications telles que atomiquement mise à jour des drapeaux, et ne peut pas être utilisé comme un pour le remplacement d'une valeur de type Boolean.

Un collègue et moi avons été à essayer de comprendre un cas d'utilisation où le AtomicBoolean ne peut pas être un substitut et la seule chose que nous pouvons penser est qu'il y a des méthodes de l'objet Boolean a que le AtomicBoolean ne le fait pas.

Est-ce la seule raison, ou y avait-il quelque chose d'autre à l'esprit quand on l'a écrit?

53voto

Nathan Hughes Points 30377

Booléen est une valeur immuable de l'objet. Il a été conçu pour être immuable et le dernier dans l'ordre de la faire respecter. java.lang.Boolean a été autour depuis la 1.0.

AtomicBoolean est mutable, et conçu pour obtenir des mises à jour de sorte que la valeur mise à jour est visible sur les threads. AtomicBoolean a été introduit avec Java 5.

Ce sont des concepts entièrement différents, c'est pourquoi AtomicBoolean n'a pas été conçu pour étendre la valeur de type Boolean. Vous ne pouvez pas remplacer un objet mutable pour un immuable sans les détruire attendus invariants du code de l'utiliser. Code attend à recevoir une valeur immuable pourrait se casser si la atomique version pourrait être passé à sa place.

Voici donc un cas d'utilisation: si AtomicBoolean a été présenté comme quelque chose qui a été substituables pour les Booléens, vous pourriez avoir un cas où une classe créée avant que ce changement pourrait raisonnablement s'attendre à ce que dans une méthode qui retourne un Booléen, il n'a pas besoin de passer une défensive copie sur le compte de Booléenne être immuable. Si la référence renvoyée arrive à obtenir initialisé à partir d'une source que les modifications apportées à l'utilisation AtomicBoolean au lieu de Booléen, qui peut maintenant être modifiée par les choses de l'appel de la méthode retournant un Booléen, par moulage AtomicBoolean.

L'atomic classes sont conçues pour travailler avec des mises à jour simultanées (comme une amélioration sur volatile), mais le moyen le plus efficace pour la conception simultanée du code est d'utiliser des valeurs inaltérables. Alors attention à ne pas confondre AtomicBoolean pour "le Booléen vous utilisez lors de l'écriture de code multithread".

34voto

manouti Points 10398

Boolean est la classe d'emballage autour de la primitive boolean . Il peut être créé automatiquement à partir de boolean par le compilateur (conversion de boxe) ou converti en un booléen (conversion de déballage). Ce n'est pas le cas pour AtomicBoolean où il s'agit d'une classe distincte conçue à des fins de simultanéité.

Par conséquent, les deux classes ont une sémantique différente au niveau de la langue:

 Boolean b = new Boolean(true);
AtomicBoolean ab = new AtomicBoolean(true);
System.out.println(true == b);  // automatic unboxing of Boolean variable
System.out.println(true == ab);  // compiler error
 

6voto

Sudicode Points 420

Un cas d'utilisation est que AtomicBoolean ne s'étend pas Boolean . Donc, si vous avez une méthode telle que:

 void foo (Boolean b) {
    doStuff();
}
 

Ensuite, vous ne pouvez pas passer un AtomicBoolean tant que paramètre à foo . (Vous devez appeler la méthode get() des AtomicBoolean .)

4voto

Dave Newton Points 93112

Ils ne sont pas automatiquement configurables, ils ne peuvent donc pas être utilisés dans des conditions conditionnelles, par exemple:

 // Explodey
if (someAtomicBoolean) {
}
 

4voto

Hanno Binder Points 3880

Exemple:

void doSomething( final Boolean flag ) {


  final boolean before = flag.booleanValue();

  do0( flag );

  final boolean after = flag.booleanValue();

  assert before == after;



  if ( flag.booleanValue() ) {
    do1();
  }

  if ( flag.booleanValue() ) {
    do2();
  }

}

peut donner un résultat différent de celui

void doSomething( final AtomicBoolean flag ) {


  final boolean before = flag.get();

  do0( flag );

  final boolean after = flag.get();

  assert (before == after) || (before != after);



  if ( flag.get() ) {
    do1();
  }

  if ( flag.get() ) {
    do2();
  }

}

parce qu'un AtomicBoolean pouvez changer sa valeur, tandis qu'un Boolean ne le peuvent pas.

Dans le premier cas, do1() et do2() sont soit tous les deux appelé ou aucun d'eux.

Dans le second cas, les deux, ou aucun d'eux ne peut être appelée que si le AtomicBooleans'valeur est modifiée en même temps.

Parce qu' Boolean a toujours été là, et a toujours été défini comme immuable, AtomicBoolean, qui a été introduit beaucoup plus tard, ne peut pas être interchangeables Boolean parce qu'il se comporte différemment et le code qui légitimement s'appuie sur l'immutabilité d'un Boolean peut se briser si cette immutabilité est détruit.

Notez que Boolean ne peut pas être substitué AtomicBoolean et vice versa. Ils sont tout simplement pas compatibles dans leur sémantique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X