7
votes

Java - La méthode statique est implicitement sur la sécurité?

Un de mes java statique est accessible par plusieurs threads. Dois-je synchroniser explicitement la méthode par mot clé synchronisée?

En arrière, j'ai lu dans un livre qui indique que

La méthode statique est implicitement du thread en toute sécurité car la méthode n'est pas un objet spécifique

.

Exemple bien connu est la mise en œuvre singleton. Dans lequel getinstance () est statique et avons-nous besoin de marquer cela comme synchronisé aussi? xxx

merci


6 commentaires

non! statique n'est pas un synonyme de synchronisé!


Si ces données statiques sont mutables, cela signifie que chaque objet voit des changements. Est-ce que c'est ce que tu veux? Peut-être pas.


Mais, la méthode n'aura qu'un seul exemplaire car il est variable de niveau de classe. À droite?


Les méthodes n'ont pas copies du tout. Je soupçonne fortement que vous avez mal compris le livre - ou vous devez le citer Verbatim. Les méthodes statiques devraient être fabriquées Safe-Safe, typiquement - mais ce n'est pas la même chose.


Les méthodes statiques ne sont pas une sate de fil simplement parce qu'elles sont statiques. Si votre classe a du champ statique, disons x = 1; et vous avez une méthode statique incrémentation du vide statique () {x ++} alors vous pouvez toujours faire face à un problème avec la condition de course. Statique signifie juste que la méthode est invoquée en classe plutôt que par exemple. Si vous synchronisez cela, cela signifie simplement que vous le synchronisez sur YourClass.class littéral plutôt que cette instance .


@Toutez-vous si ces données sont THELCONText?


5 Réponses :


4
votes

Non, ce n'est pas.

La phrase que vous citez signifie que la méthode statique n'est pas spécifique à l'objet et, en raison de la variable locale étant enregistrée dans un environnement de thread, elle ne peut être accédée qu'à partir de l'exécution locale du fil lui-même. Mais dans une méthode statique, vous pouvez accéder à un champ statique ou à un objet partagé par plusieurs threads, dans ce cas, vous ne traiterez pas d'une variable locale, mais avec quelque chose partagé entre plusieurs objets.

Dans un autre mot, étant donné que l'exécution est en sécurité, l'accès à un champ d'un objet est partagé à tous les threads qui ont accès à l'objet. Dans ce cas, vous avez un problème de concurrence qui doit être traité avec le mot clé synchronisé . Avec un mot-clé synchronisé, vous établissez une déclaration accessible d'un seul fil par heure. xxx

}


1 commentaires

"Domaine statique d'un objet" est une contradiction. Vous voulez dire "champ statique d'une classe" ou "champ statique faisant référence à un objet", cependant, des champs statiques de types primitifs ou de tableaux ont également besoin de constructions de sécurité. Notez qu'un procédé statique peut également manipuler des objets passés sous forme de paramètres, qui pourraient être partagés entre différents threads.



5
votes

statique code> Le modificateur et la sécurité du fil sont deux questions distinctes.

Vous êtes dans un étui de sécurité THEAD DEFACTO uniquement lorsque vous n'avez aucune condition de course. de
Ne pas avoir de conditions de course pour une méthode signifie que: p>

  • soit l'accès à la méthode est effectué par un thread unique Single Single strong> p> li>

  • ou par des fils simultanés mais uniquement pour la lecture d'accès fort>.
    p> li> ul>

    Ces deux choses ont zéro relation avec le fait que la méthode est statique forte> ou non. p>

    Par exemple dans ce code: P >

    public class SingletonBillPughWithEagerCreation {
    
        // executed as soon as the SingletonBillPughWithEagerCreation class is loaded by the classLoader
        private static SingletonBillPughWithEagerCreation instance = new SingletonBillPughWithEagerCreation();
    
        private SingletonBillPughWithEagerCreation() {
        }
    
        public static SingletonBillPughWithEagerCreation getInstance() {
           return instance;
        }
    }
    


0 commentaires

0
votes

Considérez l'exemple suivant. getinstance code> est appelé deux fois, par des threads A et B.

line1:public **synchronized** static Logger getInstance() {
line2:    if( instance == null ){
line3:        instance = new Logger();
line4:    }
line5:
line6:    return instance;
line7:}


1 commentaires

Cette réponse a besoin de plus de contexte. Une explication plus concise avec plus de précision à la question de l'OP est préférable.



2
votes

Il y a des réponses expliquant pourquoi ce n'est pas un fil sûr, mais pour répondre à votre citation

La méthode statique est implicitement du thread en toute sécurité car la méthode n'est pas spécifique à l'objet

L'instruction JVM Invokestatique pour des méthodes statiques Documents que

Si la méthode est synchronisée, le moniteur associé à l'objet de la classe résolue est entré ou rentré comme s'il est par exécution d'une instruction Monitorenter (§Monitorenter) dans le thread de courant.

ce qui signifie que les méthodes statiques ne sont pas intrinsèques-sûres dans un environnement concomitant, car il existe une différence entre synchronisé et méthodes statiques non synchronisées


0 commentaires

3
votes

Une méthode peut être considérée comme du thread-coffre-fort si des appels simultanés de plusieurs threads ne créeront pas de situation, où aucun espace mémoire est écrit par un fil, et simultanément écrit / lu par un autre fil en même temps.

Ceci L'exemple montre une fonction que si appelée par plusieurs threads peut causer des problèmes: p> xxx pré>

car une valeur est d'abord écrite, puis lue par plusieurs threads, et cela pourrait se produire Écrit un 5, puis le thread b écrit un 9 000, puis enfilez une sortie la phrase, car la valeur est maintenant> 9000, malgré l'entrée de 5. P>

avec une nouvelle modification de cette fonction -Safe: p>

static final int[][] matrix = new int[N][M];

static void fillMatrixColumn(final int n) {
  for (int m = 0; m < M; ++m) {
    matrix[n][m] = calculateValue(n, m);
  }
}

public static void main(String[] args)() {
  IntStream.range(0, N)
    .parallel()
    .forEach(this::fillMatrixColumn);
  printMatrix(matrix);
}


0 commentaires