2013-02-02 5 views
0

Quel est le but ou la valeur de la création d'une référence locale à une variable volatile statique qui est déjà conservée en tant que champ membre. Ce code provient de java.util.Scanner JDK 6b14 here.Variable locale utilisée pour accéder à la variable d'instance volatile

class Scanner { 
    private static volatile Pattern linePattern; 
    ... 
    private static Pattern linePattern() { 
     Pattern lp = linePattern; 
     if (lp == null) 
      linePattern = lp = Pattern.compile("..."); 
     return lp; 
    } 
    ... 
} 

The Java Tutorials: « et les écritures sont Reads atomiques pour toutes les variables déclarées volatiles (y compris les variables long et double) ... toute écriture à une variable volatile établit un avant-arrive la relation avec les lectures suivantes de cette même variable. "

Cela signifie que la lecture de la référence à l'objet Motif n'échouera pas à mi-chemin car elle a été modifiée. Le mot clé volatile est censé protéger exactement ce type d'accès, donc la variable locale en double n'est pas destinée à garantir qu'une valeur valide est renvoyée.

En outre, l'initialisation paresseuse peut être fait sur le terrain membre sans avoir besoin d'un intermédiaire variable locale:

if (linePattern == null) linePattern = Pattern.compile("..."); 

Il semble être une optimisation du code octet comme on le voit here et here. L'utilisation de variables locales produit un bytecode plus petit (moins d'instructions) et moins d'accès à la valeur réelle (qui est une lecture volatile coûteuse). Cependant, ils n'ont pas utilisé l'optimisation de la variable finale avec elle, donc je suis sceptique à l'idée de tirer cette conclusion.

Répondre

1

Cette "vitesse" des choses. L'accès aux variables volatile est coûteux. L'utilisation peut s'échapper avec cette surcharge en l'assignant à une variable de pile et en accédant à la place

2

Lazy initialization, c'est-à-dire de retarder le travail jusqu'à ce que ce soit vraiment nécessaire.

+0

mais pourquoi ne pas initialiser paresseusement le champ de membre? – xst

+0

La méthode encapsule exactement cela. Il est utilisé pour obtenir la valeur du champ et garantit qu'il est initialisé en cas de besoin. – Wormbo

+0

'if (linePattern == null) linePattern = new ...' Ceci initialiserait paresseusement le champ membre au lieu de la variable locale. – xst

0

Pour volatile champs, le linePattern peut changer entre les différentes lignes. La copie de la référence à une variable locale garantit que vous ne pouvez pas avoir un état incohérent. Par exemple, si vous aviez écrit

if (linePattern == null) 
    linePattern = Pattern.compile("..."); 

alors linePattern pourrait avoir arrêté étant nul alors que le Pattern.compile exécutait.

+0

le mot clé volatile garantit que les lectures ne se chevauchent pas, comme indiqué dans la référence (que je viens d'ajouter). Parlez-vous de volatile en C, où il est utilisé pour lire des périphériques IO mappés en mémoire? – xst

+0

Non, je parle très certainement de volatile en Java. La référence que vous avez indiquée signifie que 'linePattern' ne se chevauchera pas au milieu d'une lecture spécifique ou d'une écriture spécifique, mais si vous faites plusieurs lectures et/ou plusieurs écritures, la valeur peut être modifiée par d'autres threads dans entre ces opérations. –

1

Il garantit que la valeur retournée n'est pas NULL - même si la variable statique est définie sur NULL entre vérification et retour.

Et en même temps c'est un init paresseux non synchronisé avec une ré-initialisation si nécessaire;).

Questions connexes