53 votes

Est-il utile d'utiliser un long volatile?

J'ai parfois l'utilisation d'un volatile variable d'instance dans les cas où j'ai deux fils à la lecture de / écriture à elle et ne veulent pas les frais généraux (ou de blocage potentiel de risque) de prendre un verrou; par exemple, un thread horloge de mettre à jour périodiquement un int ID est exposé comme un getter sur certains de la classe:

public class MyClass {
  private volatile int id;

  public MyClass() {
    ScheduledExecutorService execService = Executors.newScheduledThreadPool(1);
    execService.scheduleAtFixedRate(new Runnable() {
      public void run() {
        ++id;
      }
    }, 0L, 30L, TimeUnit.SECONDS);
  }

  public int getId() {
    return id;
  }
}

Ma question: étant Donné que la JLS ne garantit que 32-bit lit sera atomique il y a tout point à jamais à l'aide d'un volatile de temps? (c'est à dire 64 bits).

Mise en garde: Veuillez ne pas répondre en disant que l'utilisation d' volatile sur synchronized est un cas de pré-optimisation; je suis bien conscient de comment / quand utiliser synchronized mais il y a des cas où l' volatile est préférable. Par exemple, lors de la définition d'un Printemps bean pour une utilisation dans une application unique-thread, j'ai tendance à privilégier volatile variables d'instance, comme il n'y a aucune garantie que le Printemps est le contexte qui va initialiser chaque bean propriétés dans le thread principal.

124voto

aioobe Points 158466

Pas sûr si je comprends votre question correctement, mais le JLS 8.3.1.4. Champs volatiles états:

Un champ peut être déclaré volatile, auquel cas la Java du modèle de mémoire garantit que tous les fils voir une cohérence de la valeur de la variable (§17.4).

et, peut-être plus important encore, JLS 17.7 Non-atomique Traitement de la double et long :

17.7 Non-atomique Traitement de la double et long
[...]
Pour l'application du langage de programmation Java modèle de mémoire, une seule écriture à un non-volatile long ou double valeur est traitée comme deux écritures: une pour chacune des moitiés de 32 bits. Il peut en résulter une situation où un thread voit les 32 premiers bits de 64 bits de la valeur à partir d'une écriture, et la seconde de 32 bits à partir d'une autre écriture. Les écritures et les lectures de la volatilité de long et double les valeurs sont toujours atomique. Écrit et se lit de références sont toujours atomique, indépendamment de si elles sont mises en œuvre (32 ou 64 bits.

C'est, la "totalité" de la variable est protégé par la volatilité de modificateur, pas seulement les deux parties. Cette tente de m'affirmant qu'il est encore plus important d'utiliser volatiles longs que c'est pour ints depuis même pas un lire est atomique pour les non-volatile longs/doubles.

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