Question Que signifie "synchronisé"?


J'ai quelques questions concernant l'utilisation et la signification de synchronized mot-clé.

  • Quelle est la signification de la synchronized mot-clé?
  • Quand les méthodes devraient-elles être synchronized?
  • Qu'est-ce que cela signifie par programme et logiquement?

818
2017-07-06 06:47


origine


Réponses:


le synchronized mot-clé est tout au sujet de différents fils de lecture et d'écriture pour les mêmes variables, objets et ressources. Ce n'est pas un sujet trivial en Java, mais voici une citation de Sun:

synchronized les méthodes permettent une simple   stratégie pour empêcher le fil   interférence et cohérence de la mémoire   erreurs: si un objet est visible   plus d'un thread, tout lit ou   écrit aux variables de cet objet sont   fait par des méthodes synchronisées.

En très, très petit mot: Lorsque vous avez deux threads qui lisent et écrivent dans la même "ressource", dites une variable nommée foo, vous devez vous assurer que ces threads accèdent à la variable de manière atomique. Sans le synchronized mot-clé, votre fil 1 peut ne pas voir le fil de changement 2 fait à fooou pire, il peut seulement être modifié à moitié. Ce ne serait pas ce à quoi vous vous attendez logiquement.

Encore une fois, c'est un sujet non trivial en Java. Pour en savoir plus, explorez les sujets ici sur SO et les Interwebs sur:

Continuez à explorer ces sujets jusqu'à ce que le nom "Brian Goetz" devient définitivement associé au terme "concurrence" dans ton cerveau.


749
2017-07-06 07:01



Eh bien, je pense que nous en avions assez des explications théoriques, alors considérez ce code

public class SOP {
    public static void print(String s) {
        System.out.println(s+"\n");
    }
}

public class TestThread extends Thread {
    String name;
    TheDemo theDemo;
    public TestThread(String name,TheDemo theDemo) {
        this.theDemo = theDemo;
        this.name = name;
        start();
    }
    @Override
    public void run() {
        theDemo.test(name);
    }
}

public class TheDemo {
    public synchronized void test(String name) {
        for(int i=0;i<10;i++) {
            SOP.print(name + " :: "+i);
            try{
                Thread.sleep(500);
            } catch (Exception e) {
                SOP.print(e.getMessage());
            }
        }
    }
    public static void main(String[] args) {
        TheDemo theDemo = new TheDemo();
        new TestThread("THREAD 1",theDemo);
        new TestThread("THREAD 2",theDemo);
        new TestThread("THREAD 3",theDemo);
    }
}

Remarque: synchronized bloque l'appel du thread suivant à la méthode test () tant que l'exécution du thread précédent n'est pas terminée. Les threads peuvent accéder à cette méthode un à la fois. Sans pour autant synchronized tous les threads peuvent accéder à cette méthode simultanément.

Lorsqu'un thread appelle la méthode synchronisée 'test' de l'objet (ici l'objet est une instance de la classe 'TheDemo') il acquiert le verrou de cet objet, tout nouveau thread ne peut pas appeler TOUTE méthode synchronisée du même objet tant que le thread précédent qui avait acquis le verrou ne libère pas le verrou.

Une chose similaire se produit quand une méthode statique synchronisée de la classe est appelée. Le thread acquiert le verrou associé à la classe (dans ce cas, toute méthode synchronisée non statique d'une instance de cette classe peut être appelée par n'importe quel thread car ce verrou au niveau de l'objet est toujours disponible). Tout autre thread ne pourra pas appeler n'importe quelle méthode synchronisée statique de la classe tant que le verrou de niveau de classe n'est pas libéré par le thread qui détient actuellement le verrou.

Sortie avec synchronisé

THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9

Sortie sans synchronisation

THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9

244
2018-05-15 13:23



le synchronized Le mot clé empêche l'accès simultané à un bloc de code ou à un objet par plusieurs threads. Par défaut, un Hashtable est synchronized, donc un seul thread peut accéder à la table à la fois.

Sur l'utilisation de non-synchronized construit comme HashMap, vous devez créer des fonctions de sécurité de thread dans votre code pour éviter les erreurs de cohérence de la mémoire.


102
2018-01-22 18:39



synchronizedsignifie que dans un environnement multi-thread, un objet ayant synchronized méthode (s) / bloc (s) ne laisse pas deux threads accéder au synchronized méthode (s) / bloc (s) de code en même temps. Cela signifie qu'un thread ne peut pas lire pendant qu'un autre thread le met à jour.

Le deuxième thread attendra jusqu'à ce que le premier thread termine son exécution. La surcharge est la vitesse, mais l'avantage est la cohérence des données.

Si votre application est un seul thread, synchronized blocs ne fournit pas d'avantages.


73
2018-01-22 18:39



le synchronized Un mot clé provoque l'obtention d'un verrou lors de la saisie de la méthode, de sorte qu'un seul thread peut exécuter la méthode en même temps (pour l'instance d'objet donnée, sauf s'il s'agit d'une méthode statique).

Ceci est souvent appelé rendre la classe thread-safe, mais je dirais que c'est un euphémisme. Bien qu'il soit vrai que la synchronisation protège l'état interne du vecteur de se corrompre, cela n'aide pas beaucoup l'utilisateur de Vector.

Considère ceci:

 if (vector.isEmpty()){
     vector.add(data);
 }

Même si les méthodes impliquées sont synchronisées, parce qu'elles sont verrouillées et déverrouillées individuellement, deux threads malheureusement chronométrés peuvent créer un vecteur avec deux éléments.

Donc en effet, vous devez également synchroniser dans votre code d'application.

Parce que la synchronisation au niveau de la méthode est a) coûteuse quand vous n'en avez pas besoin et b) insuffisante quand vous avez besoin de synchronisation, il y a maintenant des remplacements non-synchronisés (ArrayList dans le cas de Vector).

Plus récemment, le package de simultanéité a été publié, avec un certain nombre d'utilitaires intelligents qui prennent en charge les problèmes de multi-threading.


50
2017-07-06 07:09



Aperçu

Le mot-clé synchronisé en Java concerne la sécurité des threads, c'est-à-dire lorsque plusieurs threads lisent ou écrivent la même variable.
Cela peut arriver directement (en accédant à la même variable) ou indirectement (en utilisant une classe qui utilise une autre classe qui accède à la même variable).

Le mot-clé synchronized est utilisé pour définir un bloc de code dans lequel plusieurs threads peuvent accéder à la même variable de manière sûre.

Plus profond

Syntaxe sage le synchronized mot-clé prend un Object comme c'est le paramètre (appelé un objet de verrouillage), qui est ensuite suivi d'un { block of code }.

  • Lorsque l'exécution rencontre ce mot-clé, le thread actuel tente de "verrouiller / acquérir / posséder" (faites votre choix) le verrouiller l'objet et exécuter le bloc de code associé après que le verrou a été acquis.

  • Toutes les écritures dans les variables à l'intérieur du bloc de code synchronisé sont garanties pour être visibles à tous les autres threads qui exécutent de la même manière du code dans un bloc de code synchronisé en utilisant le même verrouiller l'objet.

  • Un seul thread à la fois peut contenir le verrou, pendant ce temps tous les autres threads essayant d'acquérir le même verrouiller l'objet attendra (pause leur exécution). Le verrou sera libéré lorsque l'exécution quittera le bloc de code synchronisé.

Méthodes synchronisées:

Ajouter synchronized mot-clé à une définition de méthode est égale à l'ensemble du corps de la méthode étant enveloppé dans un bloc de code synchronisé avec le verrouiller l'objetétant this  (par exemple les méthodes) et ClassInQuestion.getClass()  (pour les méthodes de classe).

- La méthode de l'instance est une méthode qui n'a pas static mot-clé.
- La méthode de classe est une méthode qui a static mot-clé.

Technique

Sans synchronisation, il n'est pas garanti dans quel ordre les lectures et les écritures se produisent, laissant éventuellement la variable avec des ordures.
(Par exemple, une variable peut se retrouver avec la moitié des bits écrits par un thread et la moitié des bits écrits par un autre thread, laissant la variable dans un état qu'aucun des threads n'a essayé d'écrire, mais un mélange des deux.)

Il n'est pas suffisant de terminer une opération d'écriture dans un thread avant qu'un autre thread le lit, car le matériel aurait pu mettre en cache la valeur de la variable et le thread de lecture verrait la valeur mise en cache à la place de ce qui était écrit il.

Conclusion

Ainsi, dans le cas de Java, vous devez suivre le modèle de mémoire Java pour vous assurer que les erreurs de thread ne se produisent pas.
En d'autres termes: Utilisez la synchronisation, les opérations atomiques ou les classes qui les utilisent pour vous sous les hottes.

Sources

http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Spécification de langage Java, 2015-02-13


20
2018-06-22 15:19



Pensez-y comme une sorte de tourniquet comme vous pourriez trouver sur un terrain de football. Il y a des vapeurs parallèles de gens qui veulent entrer, mais au tourniquet, ils sont synchronisés. Une seule personne à la fois peut passer à travers. Tous ceux qui veulent passer à travers feront l'affaire, mais ils devront peut-être attendre jusqu'à ce qu'ils puissent passer.


18
2017-07-06 07:09