Que signifie "synchronisé"?


J'ai quelques questions concernant l'utilisation et l'importance de la synchronized clé.

  • Quelle est la signification du mot-clé synchronized?
  • Quand les méthodes devraient-elles être synchronized?
  • Qu'est-ce que cela signifie par programme et logiquement?
Author: user207421, 2009-07-06

17 answers

Le mot-clé synchronized concerne différents threads lisant et écrivant dans 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 un simple stratégie pour prévenir thread interférence et cohérence de la mémoire erreurs: si un objet est visible à plus d'un fil, toutes les lectures ou les écritures sur les variables de cet objet sont fait par des méthodes synchronisées.

Dans un très, très petit mot: Lorsque vous avez deux threads qui lisent et écrivent dans la même "ressource", disons une variable nommée foo, vous devez vous assurer que ces threads accèdent à la variable de manière atomique. Sans le mot-clé synchronized, votre thread 1 peut ne pas voir le changement thread 2 fait à foo, ou pire, il peut seulement être changé à moitié. Ce ne serait pas ce que 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" devienne définitivement associé au terme"concurrence" dans votre cerveau.

 909
Author: Stu Thompson, 2018-03-30 07:18:47

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 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 object est une instance de la classe' TheDemo'), il acquiert le verrou de cet objet, tout un nouveau thread ne peut pas appeler UNE 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 lorsqu'une méthode synchronisée statique 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 en appeler 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ée

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 synchronisé

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
 304
Author: Dheeraj Sachan, 2016-11-28 05:05:34

Le mot-clé synchronized empêche l'accès simultané à un bloc de code ou à un objet par plusieurs threads. Toutes les méthodes de Hashtable sont synchronized, donc un seul thread peut exécuter l'un d'eux à un moment.

Lorsque vous utilisez des constructions non-synchronized comme HashMap, vous devez créer des fonctionnalités de sécurité des threads dans votre code pour éviter les erreurs de cohérence.

 118
Author: jmort253, 2020-03-11 22:40:53

synchronized signifie que dans un environnement multithread, un objet ayant synchronized méthode(s) bloc(s) ne laissez pas les deux threads d'accéder à la 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 plutôt que le premier thread termine son exécution. La surcharge est la vitesse, mais l'avantage est la cohérence garantie des données.

Si votre application est mono-thread, synchronized les blocs ne fournissent pas d'avantages.

 82
Author: Codemwnci, 2016-11-17 14:01:09

Le mot-clé synchronized amène un thread à obtenir 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).

Cela s'appelle souvent rendre la classe thread-safe, mais je dirais que c'est un euphémisme. S'il est vrai que la synchronisation protège l'état interne du Vecteur contre la corruption, cela n'aide généralement pas beaucoup l'utilisateur du vecteur.

Considérer ceci:

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

Même si les méthodes impliquées sont synchronisées, car 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 lorsque vous n'en avez pas besoin et b) insuffisante lorsque vous avez besoin de synchronisation, il existe maintenant des remplacements non synchronisés (ArrayList dans le cas de Vecteur).

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

 54
Author: Thilo, 2009-07-06 07:09:33

Aperçu

Le mot-clé synchronisé en Java a à voir avec la sécurité des threads, c'est-à-dire lorsque plusieurs threads lisent ou écrivent la même variable.
Cela peut se produire 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 où plusieurs threads peuvent accéder à la même variable de manière sûre.

Plus Profond

Syntaxiquement le mot-clé synchronized prend un Object comme 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 essaie de "verrouiller/acquérir/posséder" (faites votre choix) l'objet lock et exécute le bloc de code associé après l'acquisition du verrou.

  • Toutes les écritures dans des variables à l'intérieur du bloc de code synchronisé sont garanties pour être visibles par tous les autres threads qui de même exécute le code à l'intérieur d'un bloc de code synchronisé en utilisant le même objet de verrouillage.

  • Un seul thread à la fois peut contenir le verrou, pendant lequel tous les autres threads essayant d'acquérir le même objet de verrouillage attendront (interrompront leur exécution). Le verrou sera libéré lorsque l'exécution quitte le bloc de code synchronisé.

Méthodes synchronisées:

L'ajout du mot-clé synchronized à une définition de méthode est égal à la méthode entière corps étant enveloppé dans un bloc de code synchronisé avec l'objet lock étant this (par exemple les méthodes) et ClassInQuestion.getClass() (pour les méthodes de classe) .

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

Technique

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

Il ne suffit pas de terminer une opération d'écriture dans un thread avant qu'un autre thread ne le lise, 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 au lieu de ce qui a été écrit pour elle.

Conclusion

Ainsi, dans le cas de Java, vous devez suivre le modèle de mémoire Java pour vous assurer que les erreurs de threading 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 du langage Java® , 2015-02-13

 29
Author: Gima, 2016-06-29 14:23:45

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

 21
Author: paul, 2009-07-06 07:09:52

Quel est le mot-clé synchronisé?

Les threads communiquent principalement en partageant l'accès aux champs et aux objets auxquels se réfèrent les champs de référence. Cette forme de communication est extrêmement efficace, mais rend possible deux types d'erreurs: interférences de thread et erreurs de cohérence mémoire. L'outil nécessaire pour éviter ces erreurs est la synchronisation.

Les blocs ou méthodes synchronisés empêchent les interférences de thread et s'assurent que les données sont cohérent. À tout moment, un seul thread peut accéder à un bloc ou à une méthode synchronisée (section critique) en acquérant un verrou. D'autres threads attendront la libération du verrou pour accéder à la section critique .

Quand les méthodes sont-elles synchronisées?

Les méthodes

Sont synchronisées lorsque vous ajoutez synchronized à la définition ou à la déclaration de méthode. Vous pouvez également synchroniser un bloc de code particulier dans une méthode.

Qu'est-ce que cela signifie pro grammaticalement et logiquement?

Cela signifie qu'un seul thread peut accéder à la section critique en acquérant un verrou. À moins que ce thread ne libère ce verrou, tous les autres threads devront attendre pour acquérir un verrou. Ils n'ont pas accès pour entrersection critique sans verrouillage d'acquisition.

Cela ne peut pas être fait avec une magie. Il est de la responsabilité du programmeur d'identifier section(s) critique (s) dans l'application et de la protéger en conséquence. Java fournit un cadre pour garder votre application, mais où et ce que toutes les sections à garder est la responsabilité du programmeur.

Plus de détails à partir de la documentation java page

Verrous intrinsèques et synchronisation:

La synchronisation est construite autour d'une entité interne connue sous le nom de verrouillage intrinsèque ou verrouillage du moniteur. Les verrous intrinsèques jouent un rôle dans les deux aspects de la synchronisation: imposer l'accès exclusif à l'état d'un objet et établir happens-before des relations essentielles à la visibilité.

Chaque objet a un verrou intrinsèque qui lui est associé. Par convention, un thread qui a besoin d'un accès exclusif et cohérent aux champs d'un objet doit acquérir le verrou intrinsèque de l'objet avant d'y accéder, puis relâcher le verrou intrinsèque lorsque c'est fait avec eux.

On dit qu'un thread possède le verrou intrinsèque entre le moment où il a acquis le verrou et libéré le verrou. , tant Qu'un thread possède un verrou intrinsèque, aucun autre thread ne peut acquérir le même verrou. L'autre thread se bloque lorsqu'il tente d'acquérir le verrou.

Lorsqu'un thread libère un verrou intrinsèque, une relation se produit avant qu'il ne soit établi entre cette action et toute acquisition ultérieure du même verrou.

La synchronisation des méthodes a deux effets :

Tout d'Abord, il n'est pas possible pour deux invocations de méthodes synchronisées sur le même objet entrelacement.

Lorsqu'un thread exécute une méthode synchronisée pour un objet, tous les autres threads qui invoquent des méthodes synchronisées pour le même bloc d'objet (suspendent l'exécution) jusqu'à ce que le premier thread soit terminé avec l'objet.

Deuxièmement, lorsqu'une méthode synchronisée se termine, elle établit automatiquement une relation happens-before avec toute invocation ultérieure d'une méthode synchronisée pour le même objet.

Cela garantit que les changements à l'état de l'objet sont visibles pour tous les threads.

Recherchez d'autres alternatives à la synchronisation dans:

Éviter synchronisé (ceci) en Java?

 16
Author: Ravindra babu, 2017-07-24 16:22:21

Synchronized normal method équivalent à Synchronized statement (utilisez ceci)

class A {
    public synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(this) {
             // all function code
        }
    } 
}

Synchronized static method équivalent à Synchronized statement (utilisation de la classe)

class A {
    public static synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(A.class) {
             // all function code
        }
    } 
}

Instruction synchronisée (en utilisant une variable)

class A {
    private Object lock1 = new Object();

    public void methodA() {
        synchronized(lock1 ) {
             // all function code
        }
    } 
}

Pour synchronized, nous avons à la fois Synchronized Methods et Synchronized Statements. Toutefois, Synchronized Methods est similaire à Synchronized Statements, donc nous avons juste besoin de comprendre Synchronized Statements.

=> Fondamentalement, nous aurons

synchronized(object or class) { // object/class use to provides the intrinsic lock
   // code 
}

Voici 2 pense que aider à comprendre synchronized

  • Chaque objet/classe a un intrinsic lock associé.
  • Quand un thread appelle un synchronized statement, il acquiert automatiquement le intrinsic lock pour cet objet synchronized statement's et le libère lorsque la méthode revient. Aussi longtemps qu'un thread possède un intrinsic lock, AUCUN autre thread ne peut acquérir la MEME lock => thread-safe.

=> Quand un thread A appelle synchronized(this){// code 1} => tout le code de bloc (à l'intérieur de la classe) où ont synchronized(this) et tout synchronized normal method (à l'intérieur de la classe) est verrouillé parce que MÊME lock. Il s'exécutera après thread A unlock ("// code 1" terminé).

Ce comportement est similaire à synchronized(a variable){// code 1} ou synchronized(class).

MÊME VERROU = > verrou (ne dépend pas de quelle méthode? ou quelles déclarations?)

Utiliser une méthode synchronisée ou des instructions synchronisées?

Je préfère synchronized statements parce qu'il est plus extensible. Exemple, à l'avenir, vous n'avez besoin que de synchroniser une partie de la méthode. Par exemple, vous avez 2 méthodes synchronisées et il n'en a aucun pertinent l'un pour l'autre, mais lorsqu'un thread exécute une méthode, il bloque le autre méthode (il peut empêcher par l'utilisation synchronized(a variable)).

Cependant, appliquer la méthode synchronisée est simple et le code semble simple. Pour certaines classes, il n'y a qu'une seule méthode synchronisée, ou toutes les méthodes synchronisées de la classe pertinentes les unes par rapport aux autres = > nous pouvons utiliser {[29] } pour rendre le code plus court et facile à comprendre

Note

(ce n'est pas pertinent pour beaucoup à synchronized, c'est la différence entre l'objet et la classe ou none-static et static).

  • Lorsque vous utilisez synchronized ou méthode normale ou synchronized(this) ou synchronized(non-static variable) il synchronisera la base sur chaque instance d'objet.
  • Lorsque vous utilisez synchronized ou une méthode statique ou synchronized(class) ou synchronized(static variable), il sera synchronisé sur la base de la classe

Référence

Https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

J'espère que ça aidera

 12
Author: Phan Van Linh, 2018-04-02 01:19:18

Voici une explication de Les tutoriels Java.

Considérez le code suivant:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

Si count est une instance de SynchronizedCounter, la synchronisation de ces méthodes a deux effets:

  • Premièrement, il n'est pas possible pour deux invocations de méthodes synchronisées sur le même objet de s'entrelacer. Lorsqu'un thread exécute une méthode synchronisée pour un objet, tous les autres threads qui invoquent des méthodes synchronisées pour le même bloc d'objet (suspendre l'exécution) jusqu'à ce que le premier thread soit terminé avec l'objet.
  • Deuxièmement, lorsqu'une méthode synchronisée se termine, elle établit automatiquement une relation happens-before avec toute invocation ultérieure d'une méthode synchronisée pour le même objet. Cela garantit que les modifications de l'état de l'objet sont visibles par tous les threads.
 11
Author: Shahryar Saljoughi, 2018-12-10 08:30:38

À ma connaissance synchronisé signifie essentiellement que le compilateur écrit un moniteur.entrez et surveillez.sortez autour de votre méthode. En tant que tel, il peut être thread safe selon la façon dont il est utilisé (ce que je veux dire, c'est que vous pouvez écrire un objet avec des méthodes synchronisées qui n'est pas threadsafe en fonction de ce que fait votre classe).

 9
Author: Spence, 2009-07-06 07:01:35

Ce qui manque aux autres réponses est un aspect important: barrières de mémoire. La synchronisation des threads se compose essentiellement de deux parties: la sérialisation et la visibilité. Je conseille à tout le monde de Google pour "barrière de mémoire jvm", car il s'agit d'un sujet non trivial et extrêmement important (si vous modifiez les données partagées accessibles par plusieurs threads). Après avoir fait cela, je conseille de regarder java.util.les classes de paquets simultanés qui aident à éviter d'utiliser la synchronisation explicite, qui à son tour aide à garder les programmes simples et efficaces, peut-être même à prévenir les blocages.

Un tel exemple est ConcurrentLinkedDeque. Avec le modèle de commande , il permet de créer des threads de travail très efficaces en insérant les commandes dans la file d'attente concurrente-pas de synchronisation explicite nécessaire, pas de blocages possibles, pas de sleep() explicite nécessaire, il suffit d'interroger la file d'attente en appelant take().

En bref: la" synchronisation de la mémoire " se produit implicitement lorsque vous démarrez un thread, un thread se termine, vous lisez une variable volatile, vous déverrouillez un moniteur (laissez un bloc/fonction synchronisé) etc. Cette "synchronisation" affecte (dans un sens "chasse") toutes les écritures effectuées avant cette action particulière. Dans le cas de ce qui précède ConcurrentLinkedDeque , la documentation "dit":

Effets de cohérence mémoire: Comme pour les autres collections simultanées, actions dans un thread avant de placer un objet dans un ConcurrentLinkedDeque produira avant de les actions postérieures à l'accès ou la suppression de cet élément du ConcurrentLinkedDeque dans un autre fil.

Ce comportement implicite est un aspect quelque peu pernicieux car la plupart des programmeurs Java sans beaucoup d'expérience en prendront juste beaucoup à cause de cela. Et puis soudainement trébucher sur ce thread après que Java ne fasse pas ce qu'il est "censé" faire en production où il y a une charge de travail différente -- et c'est joli difficile de tester les problèmes de concurrence.

 5
Author: user1050755, 2017-09-10 23:08:59

Synchronized signifie simplement que plusieurs threads s'ils sont associés à un seul objet peuvent empêcher la lecture et l'écriture sales si le bloc synchronized est utilisé sur un objet particulier. Pour vous donner plus de clarté , prenons un exemple :

class MyRunnable implements Runnable {
    int var = 10;
    @Override
    public void run() {
        call();
    }

    public void call() {
        synchronized (this) {
            for (int i = 0; i < 4; i++) {
                var++;
                System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
            }
        }
    }
}

public class MutlipleThreadsRunnable {
    public static void main(String[] args) {
        MyRunnable runnable1 = new MyRunnable();
        MyRunnable runnable2 = new MyRunnable();
        Thread t1 = new Thread(runnable1);
        t1.setName("Thread -1");
        Thread t2 = new Thread(runnable2);
        t2.setName("Thread -2");
        Thread t3 = new Thread(runnable1);
        t3.setName("Thread -3");
        t1.start();
        t2.start();
        t3.start();
    }
}

Nous avons créé deux objets de classe MyRunnable , runnable1 étant partagé avec le thread 1 et thread 3 & runnable2 étant partagé avec le thread 2 uniquement. Maintenant, lorsque t1 et t3 démarrent sans être synchronisés, la sortie PFB suggère que les deux threads 1 et 3 affectant simultanément la valeur var où pour le thread 2 , var a sa propre mémoire.

Without Synchronized keyword

    Current Thread Thread -1 var value 11
    Current Thread Thread -2 var value 11
    Current Thread Thread -2 var value 12
    Current Thread Thread -2 var value 13
    Current Thread Thread -2 var value 14
    Current Thread Thread -1 var value 12
    Current Thread Thread -3 var value 13
    Current Thread Thread -3 var value 15
    Current Thread Thread -1 var value 14
    Current Thread Thread -1 var value 17
    Current Thread Thread -3 var value 16
    Current Thread Thread -3 var value 18

En utilisant Synchronzied, le thread 3 attend que le thread 1 se termine dans tous les scénarios. Il y a deux verrous acquis , un sur runnable1 partagé par le thread 1 et le thread 3 et un autre sur runnable2 partagé par le thread 2 uniquement.

Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18
 3
Author: paras4all, 2017-06-08 18:41:15

Synchronized simple signifie qu'aucun thread ne peut accéder au bloc/méthode simultanément. Lorsque nous disons que tout bloc / méthode d'une classe est synchronisé, cela signifie qu'un seul thread peut y accéder à la fois. En interne, le thread qui tente d'y accéder prend d'abord un verrou sur cet objet et tant que ce verrou n'est pas disponible, aucun autre thread ne peut accéder aux méthodes/blocs synchronisés de cette instance de la classe.

Remarque un autre thread peut accéder à une méthode du même objet qui est non défini pour être synchronisé. Un thread peut libérer le verrou en appelant

Object.wait()
 1
Author: Aniket Thakur, 2013-05-19 08:11:45

En java pour empêcher plusieurs threads de manipuler une variable partagée, nous utilisons le mot clé synchronized. Permet de le comprendre à l'aide de l'exemple suivant:

Dans l'exemple, j'ai défini deux threads et les ai nommés incrément et décrémentation. Le thread d'incrément augmente la valeur de la variable partagée (counter) du même montant que le thread de décrémentation le diminue, c'est-à-dire 5000 fois qu'il est augmenté (ce qui donne 5000 + 0 = 5000) et 5000 fois que nous diminuons (ce qui donne 5000 - 5000 = 0).

Programme sans synchronized clé:

class SynchronizationDemo {

    public static void main(String[] args){

        Buffer buffer = new Buffer();                   

        MyThread incThread = new MyThread(buffer, "increment");
        MyThread decThread = new MyThread(buffer, "decrement"); 

        incThread.start();
        decThread.start();  
       
        try {
          incThread.join();
          decThread.join();
        }catch(InterruptedException e){ }

        System.out.println("Final counter: "+buffer.getCounter());
    }
}

class Buffer {
    private int counter = 0; 
    public void inc() { counter++; }
    public void dec() { counter--; } 
    public int getCounter() { return counter; }
}

class MyThread extends Thread {

    private String name;
    private Buffer buffer;

    public MyThread (Buffer aBuffer, String aName) {            
        buffer = aBuffer; 
        name = aName; 
    }

    public void run(){
        for (int i = 0; i <= 5000; i++){
            if (name.equals("increment"))
                buffer.inc();
            else
                buffer.dec();                           
        }
    }
}

Si nous exécutons le programme ci-dessus, nous nous attendons à ce que la valeur du tampon soit la même car incrémenter et décrémenter le tampon de la même quantité entraînerait la valeur initiale avec laquelle nous avons commencé, n'est-ce pas ?. Permet de voir la sortie:

entrez la description de l'image ici

Comme vous pouvez le voir, peu importe le nombre de fois que nous exécutons le programme, nous obtenons un résultat différent, chaque thread manipulant le counter en même temps. Si nous pouvions réussir à laisser le seul thread à incrémenter d'abord la variable partagée, puis le second à la décrémenter ou vice versa, nous obtiendrons alors le bon résultat qui est exactement ce qui peut être fait avec le mot-clé synchronized en ajoutant simplement le mot-clé synchronized avant les méthodes inc et dec de Buffer comme ceci:

Programme avec synchronized clé:

// rest of the code

class Buffer {
    private int counter = 0; 
    // added synchronized keyword to let only one thread
    // be it inc or dec thread to manipulate data at a time
    public synchronized void inc() { counter++; }
    public synchronized void dec() { counter--; } 
    public int getCounter() { return counter; }
}

// rest of the code

Et la sortie:

entrez la description de l'image ici

Peu importe combien de fois nous l'exécutons, nous obtenons la même sortie que 0

 0
Author: Ahtisham, 2020-09-05 04:12:46

volatile[Sur] => synchronized

synchronized bloc en Java est un moniteur dans le multithreading. synchronized bloc avec le même objet/classe peut être exécuté par un seul thread, tous les autres sont en attente. Cela peut aider avec race condition situation lorsque plusieurs threads tentent de mettre à jour la même variable.

Java 5 étendue synchronized, en soutenant happens-before[Sur]

Un déverrouillage (sortie de bloc ou de méthode synchronisée) d'un moniteur se produit-avant chaque verrouiller (entrée de bloc ou de méthode synchronisée) de ce même moniteur.

L'étape suivante est java.util.concurrent

 0
Author: yoAlex5, 2020-09-05 17:21:54

Synchronized est un mot-clé en Java qui est utilisé pour faire se produit avant la relation dans l'environnement multithreading pour éviter l'incohérence de la mémoire et l'erreur d'interférence de thread.

 -6
Author: Sharad, 2014-06-19 09:05:26