java synchronized what is thread synchronization java
Ce didacticiel explique la synchronisation des threads en Java ainsi que des concepts associés tels que Java Lock, Race Condition, Mutex, Java Volatile & Deadlock en Java:
Dans un environnement multithreading où plusieurs threads sont impliqués, il y a forcément des conflits lorsque plusieurs threads essaient d'obtenir la même ressource en même temps. Ces conflits entraînent une «condition de concurrence» et donc le programme produit des résultats inattendus.
Par exemple, un seul fichier est mis à jour par deux threads. Si un thread T1 est en train de mettre à jour ce fichier, dites une variable. Maintenant que cette mise à jour par T1 est toujours en cours, disons que le deuxième thread T2 met également à jour la même variable. De cette façon, la variable donnera des résultats erronés.
=> Regardez la série complète de formations Java ici.
Lorsque plusieurs threads sont impliqués, nous devons gérer ces threads de manière à ce qu'une ressource soit accessible par un seul thread à la fois. Dans l'exemple ci-dessus, le fichier auquel les deux threads accèdent doit être géré de telle manière que T2 ne puisse pas accéder au fichier tant que T1 n'a pas fini d'y accéder.
Cela se fait en Java en utilisant ' Synchronisation des threads ».
Ce que vous apprendrez:
- Synchronisation des threads en Java
- Multi-threading sans synchronisation
- Multi-threading avec synchronisation
- Conclusion
Synchronisation des threads en Java
Comme Java est un langage multi-threads, la synchronisation des threads a beaucoup d'importance en Java car plusieurs threads s'exécutent en parallèle dans une application.
Nous utilisons des mots clés «Synchronisé» et 'volatil' pour réaliser la synchronisation en Java
Nous avons besoin d'une synchronisation lorsque l'objet ou la ressource partagé est modifiable. Si la ressource est immuable, les threads ne liront la ressource que simultanément ou individuellement.
Dans ce cas, nous n'avons pas besoin de synchroniser la ressource. Dans ce cas, JVM s'assure que Le code synchronisé Java est exécuté par un thread à la fois .
La plupart du temps, l'accès simultané aux ressources partagées en Java peut introduire des erreurs telles que «Incohérence de la mémoire» et «interférence de thread». Pour éviter ces erreurs, nous devons opter pour la synchronisation des ressources partagées afin que l'accès à ces ressources soit mutuellement exclusif.
Nous utilisons un concept appelé Moniteurs pour mettre en œuvre la synchronisation. Un moniteur n'est accessible que par un seul thread à la fois. Lorsqu'un thread obtient le verrou, nous pouvons dire que le thread est entré dans le moniteur.
Lorsqu'un moniteur est accédé par un thread particulier, le moniteur est verrouillé et tous les autres threads essayant d'entrer dans le moniteur sont suspendus jusqu'à ce que le thread d'accès se termine et libère le verrou.
À l'avenir, nous discuterons de la synchronisation en Java en détail dans ce didacticiel. Voyons maintenant quelques concepts de base liés à la synchronisation en Java.
Condition de course à Java
Dans un environnement multithread, lorsque plusieurs threads tentent d'accéder à une ressource partagée pour écrire simultanément, plusieurs threads se font la course pour terminer l'accès à la ressource. Cela donne lieu à une «condition de course».
Une chose à considérer est qu'il n'y a pas de problème si plusieurs threads essaient d'accéder à une ressource partagée uniquement pour la lecture. Le problème survient lorsque plusieurs threads accèdent à la même ressource en même temps.
Les conditions de course se produisent en raison d'un manque de synchronisation correcte des threads dans le programme. Lorsque nous synchronisons correctement les threads de telle sorte qu'à la fois, un seul thread accède à la ressource et que la condition de concurrence cesse d'exister.
Alors, comment pouvons-nous détecter la condition de course?
La meilleure façon de détecter une condition de concurrence est la révision du code. En tant que programmeur, nous devons examiner le code attentivement pour vérifier les conditions de concurrence potentielles qui pourraient se produire.
Verrous / Moniteurs en Java
Nous avons déjà mentionné que nous utilisons des moniteurs ou des verrous pour implémenter la synchronisation. Le moniteur ou le verrou est une entité interne et est associé à chaque objet. Ainsi, chaque fois qu'un thread a besoin d'accéder à l'objet, il doit d'abord acquérir le verrou ou le moniteur de son objet, travailler sur l'objet puis libérer le verrou.
Les verrous en Java ressembleront à ceux ci-dessous:
public class Lock { private boolean isLocked = false; public synchronized void lock() throws InterruptedException { while(isLocked) { wait(); } isLocked = true; } public synchronized void unlock(){ isLocked = false; notify(); } }
Comme indiqué ci-dessus, nous avons une méthode lock () qui verrouille l'instance. Tous les threads appelant la méthode lock () seront bloqués jusqu'à ce que les ensembles de méthodes unblock () soient verrouillés sur false et notifient tous les threads en attente.
Quelques conseils à retenir sur les verrous:
- En Java, chaque objet possède un verrou ou un moniteur. Ce verrou est accessible par un thread.
- À la fois, un seul thread peut acquérir ce moniteur ou ce verrou.
- Le langage de programmation Java fournit un mot-clé Synchronized »qui nous permet de synchroniser les threads en créant un bloc ou une méthode synchronisé.
- Les ressources partagées auxquelles les threads doivent accéder sont conservées sous ce bloc / méthode synchronisé.
Mutex en Java
Nous avons déjà expliqué que dans un environnement multithread, des conditions de concurrence peuvent se produire lorsque plusieurs threads tentent d'accéder simultanément aux ressources partagées et que les conditions de concurrence entraînent une sortie inattendue.
La partie du programme qui tente d'accéder à la ressource partagée est appelée 'Section critique' . Pour éviter l'apparition de conditions de concurrence, il est nécessaire de synchroniser l'accès à la section critique. En synchronisant cette section critique, nous nous assurons qu'un seul thread peut accéder à la section critique à la fois.
Le type le plus simple de synchroniseur est le «mutex». Mutex garantit qu'à une instance donnée, un seul thread peut exécuter la section critique.
Le mutex est similaire au concept de moniteurs ou de verrous dont nous avons discuté ci-dessus. Si un thread a besoin d'accéder à une section critique, il doit acquérir le mutex. Une fois le mutex acquis, le thread accède au code de la section critique et, une fois terminé, libère le mutex.
Les autres threads qui attendent d'accéder à la section critique seront bloqués entre-temps. Dès que le thread contenant le mutex le libère, un autre thread entrera dans la section critique.
Questions d'entretien sur le réglage des performances d'Oracle 11g
Il existe plusieurs façons d'implémenter un mutex en Java.
- Utilisation d'un mot-clé synchronisé
- Utilisation du sémaphore
- Utilisation de ReentrantLock
Dans ce tutoriel, nous discuterons de la première approche, à savoir la synchronisation. Les deux autres approches - Semaphore et ReentrantLock seront discutées dans le prochain tutoriel dans lequel nous discuterons du package concurrent java.
Mot-clé synchronisé
Java fournit un mot-clé «synchronisé» qui peut être utilisé dans un programme pour marquer une section critique. La section critique peut être un bloc de code ou une méthode complète. Ainsi, un seul thread peut accéder à la section critique marquée par le mot clé Synchronized.
Nous pouvons écrire les parties simultanées (parties qui s'exécutent simultanément) pour une application à l'aide du mot clé Synchronized. Nous nous débarrassons également des conditions de concurrence en créant un bloc de code ou une méthode Synchronized.
Lorsque nous marquons un bloc ou une méthode synchronisée, nous protégeons les ressources partagées à l'intérieur de ces entités contre l'accès simultané et donc la corruption.
Types de synchronisation
Il existe 2 types de synchronisation comme expliqué ci-dessous:
# 1) Synchronisation des processus
La synchronisation de processus implique plusieurs processus ou threads s'exécutant simultanément. Ils atteignent finalement un état où ces processus ou threads s'engagent dans une séquence d'actions spécifique.
# 2) Synchronisation des threads
Dans la synchronisation des threads, plusieurs threads tentent d'accéder à un espace partagé. Les threads sont synchronisés de telle manière que l'espace partagé n'est accessible que par un thread à la fois.
La synchronisation des processus sort du cadre de ce didacticiel. Par conséquent, nous ne discuterons que de la synchronisation des threads ici.
En Java, nous pouvons utiliser le mot-clé synchronized avec:
- Un bloc de code
- Une méthode
Les types ci-dessus sont les types mutuellement exclusifs de synchronisation de threads. L'exclusion mutuelle empêche les threads qui accèdent aux données partagées d'interférer les uns avec les autres.
L'autre type de synchronisation de threads est la «communication InterThread» basée sur la coopération entre threads. La communication entre threads sort du cadre de ce didacticiel.
Avant de procéder à la synchronisation des blocs et des méthodes, implémentons un programme Java pour démontrer le comportement des threads lorsqu'il n'y a pas de synchronisation.
Multi-threading sans synchronisation
Le programme Java suivant comporte plusieurs threads qui ne sont pas synchronisés.
class PrintCount { //method to print the thread counter public void printcounter() { try { for(int i = 5; i > 0; i--) { System.out.println('Counter ==> ' + i ); } } catch (Exception e) { System.out.println('Thread interrupted.'); } } } //thread class class ThreadCounter extends Thread { private Thread t; private String threadName; PrintCount PD; //class constructor for initialization ThreadCounter( String name, PrintCount pd) { threadName = name; PD = pd; } //run method for thread public void run() { PD.printcounter(); System.out.println('Thread ' + threadName + ' exiting.'); } //start method for thread public void start () { System.out.println('Starting ' + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } } } public class Main { public static void main(String args()) { PrintCount PD = new PrintCount(); //create two instances of thread class ThreadCounter T1 = new ThreadCounter( 'ThreadCounter_1 ', PD ); ThreadCounter T2 = new ThreadCounter( 'ThreadCounter_2 ', PD ); //start both the threads T1.start(); T2.start(); // wait for threads to end try { T1.join(); T2.join(); } catch ( Exception e) { System.out.println('Interrupted'); } } }
Production
À partir de la sortie, nous pouvons voir que comme les threads ne sont pas synchronisés, la sortie est incohérente. Les deux threads démarrent puis affichent le compteur l'un après l'autre. Les deux fils sortent à la fin.
À partir du programme donné, le premier thread doit avoir quitté après l'affichage des valeurs de compteur, puis le deuxième thread doit avoir commencé à afficher les valeurs de compteur.
Passons maintenant à la synchronisation et commençons par la synchronisation des blocs de code.
Bloc de code synchronisé
Un bloc synchronisé est utilisé pour synchroniser un bloc de code. Ce bloc se compose généralement de quelques lignes. Un bloc synchronisé est utilisé lorsque nous ne voulons pas qu'une méthode entière soit synchronisée.
Par exemple, nous avons une méthode avec disons 75 lignes de code. Sur cela, seules 10 lignes de code doivent être exécutées par un thread à la fois. Dans ce cas, si nous faisons en sorte que toute la méthode soit synchronisée, cela représentera un fardeau pour le système. Dans de telles situations, nous optons pour des blocs synchronisés.
La portée de la méthode synchronisée est toujours plus petite que celle d'une méthode synchronisée. Une méthode synchronisée verrouille un objet d'une ressource partagée qui doit être utilisée par plusieurs threads.
La syntaxe générale d'un bloc synchronisé est la suivante:
synchronized (lock_object){ //synchronized code statements }
Ici, 'lock_object' est une expression de référence d'objet sur laquelle le verrou doit être obtenu. Ainsi, chaque fois qu’un thread veut accéder aux instructions synchronisées à l’intérieur du bloc pour l’exécution, il doit acquérir le verrou sur le moniteur ‘lock_object’.
Comme déjà discuté, le mot clé synchronized garantit qu'un seul thread peut acquérir un verrou à la fois et tous les autres threads doivent attendre que le thread contenant le verrou se termine et libère le verrou.
Noter
- Une «NullPointerException» est lancée si le lock_object utilisé est Null.
- Si un thread dort tout en maintenant le verrou, le verrou n'est pas libéré. Les autres threads ne pourront pas accéder à l'objet partagé pendant ce temps de veille.
Nous allons maintenant présenter l'exemple ci-dessus qui a déjà été implémenté avec de légères modifications. Dans le programme précédent, nous n'avons pas synchronisé le code. Nous allons maintenant utiliser le bloc synchronisé et comparer la sortie.
site Web pour convertir des vidéos youtube en mp3
Multi-threading avec synchronisation
Dans le programme Java ci-dessous, nous utilisons un bloc synchronisé. Dans la méthode run, nous synchronisons le code des lignes qui impriment le compteur pour chaque thread.
class PrintCount { //print thread counter public void printCounter() { try { for(int i = 5; i > 0; i--) { System.out.println('Counter ==> ' + i ); } } catch (Exception e) { System.out.println('Thread interrupted.'); } } } //thread class class ThreadCounter extends Thread { private Thread t; private String threadName; PrintCount PD; //class constructor for initialization ThreadCounter( String name, PrintCount pd) { threadName = name; PD = pd; } //run () method for thread with synchronized block public void run() { synchronized(PD) { PD.printCounter(); } System.out.println('Thread ' + threadName + ' exiting.'); } //start () method for thread public void start () { System.out.println('Starting ' + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } } } public class Main { public static void main(String args()) { PrintCount PD = new PrintCount(); //create thread instances ThreadCounter T1 = new ThreadCounter( 'Thread_1 ', PD ); ThreadCounter T2 = new ThreadCounter( 'Thread_2 ', PD ); //start both the threads T1.start(); T2.start(); // wait for threads to end try { T1.join(); T2.join(); } catch ( Exception e) { System.out.println('Interrupted'); } } }
Production
Maintenant, la sortie de ce programme utilisant un bloc synchronisé est assez cohérente. Comme prévu, les deux threads commencent à s'exécuter. Le premier thread a fini d'afficher les valeurs du compteur et se termine. Ensuite, le deuxième thread affiche les valeurs du compteur et se termine.
Méthode synchronisée
Discutons de la méthode synchronisée dans cette section. Nous avons vu précédemment que nous pouvons déclarer un petit bloc composé de moins de lignes de code en tant que bloc synchronisé. Si nous voulons que la fonction entière soit synchronisée, nous pouvons déclarer une méthode comme synchronisée.
Lorsqu'une méthode est synchronisée, un seul thread pourra effectuer un appel de méthode à la fois.
La syntaxe générale pour écrire une méthode synchronisée est:
synchronized method_name (parameters){ //synchronized code }
Tout comme un bloc synchronisé, dans le cas d'une méthode synchronisée, nous avons besoin d'un lock_object qui sera utilisé par les threads accédant à la méthode synchronisée.
Pour la méthode synchronisée, l'objet de verrouillage peut être l'un des suivants:
- Si la méthode synchronisée est statique, alors l’objet de verrouillage est donné par l’objet ‘.class’.
- Pour une méthode non statique, l'objet de verrouillage est donné par l'objet courant, c'est-à-dire «cet» objet.
Une caractéristique particulière du mot-clé synchronisé est qu'il est rentrant. Cela signifie qu'une méthode synchronisée peut appeler une autre méthode synchronisée avec le même verrou. Ainsi, un thread qui détient le verrou peut accéder à une autre méthode synchronisée sans avoir à acquérir un verrou différent.
La méthode synchronisée est illustrée à l'aide de l'exemple ci-dessous.
class NumberClass { //synchronized method to print squares of numbers synchronized void printSquares(int n) throws InterruptedException { //iterate from 1 to given number and print the squares at each iteration for (int i = 1; i <= n; i++) { System.out.println(Thread.currentThread().getName() + ' :: '+ i*i); Thread.sleep(500); } } } public class Main { public static void main(String args()) { final NumberClass number = new NumberClass(); //create thread Runnable thread = new Runnable() { public void run() { try { number.printSquares(3); } catch (InterruptedException e) { e.printStackTrace(); } } }; //start thread instance new Thread(thread, 'Thread One').start(); new Thread(thread, 'Thread Two').start(); } }
Production
Dans le programme ci-dessus, nous avons utilisé une méthode synchronisée pour imprimer les carrés d'un nombre. La limite supérieure du nombre est transmise à la méthode en tant qu'argument. Puis à partir de 1, les carrés de chaque nombre sont imprimés jusqu'à ce que la limite supérieure soit atteinte.
Dans la fonction principale, l'instance de thread est créée. Chaque instance de thread reçoit un nombre pour imprimer des carrés.
Comme mentionné ci-dessus, lorsqu'une méthode à synchroniser est statique, alors l'objet de verrouillage est impliqué dans la classe et non dans l'objet. Cela signifie que nous allons verrouiller sur la classe et non sur l'objet. C'est ce qu'on appelle la synchronisation statique.
Un autre exemple est donné ci-dessous.
class Table{ //synchronized static method to print squares of numbers synchronized static void printTable(int n){ for(int i=1;i<=10;i++){ System.out.print(n*i + ' '); try{ Thread.sleep(400); }catch(Exception e){} } System.out.println(); } } //thread class Thread_One class Thread_One extends Thread{ public void run(){ Table.printTable(2); } } //thread class Thread_Two class Thread_Two extends Thread{ public void run(){ Table.printTable(5); } } public class Main{ public static void main(String t()){ //create instances of Thread_One and Thread_Two Thread_One t1=new Thread_One (); Thread_Two t2=new Thread_Two (); //start each thread instance t1.start(); t2.start(); } }
Production
Dans le programme ci-dessus, nous imprimons des tables de multiplication de nombres. Chaque numéro dont la table doit être imprimée est une instance de fil de classe de fil différente. Ainsi, nous imprimons des tables de multiplication de 2 et 5, nous avons donc deux classes thread_one et thread_two pour imprimer les tables 2 et 5 respectivement.
Pour résumer, le mot-clé Java synchronized remplit les fonctions suivantes:
- Le mot-clé synchronized en Java garantit un accès mutuellement exclusif aux ressources partagées en fournissant un mécanisme de verrouillage. Le verrouillage empêche également les conditions de course.
- En utilisant le mot-clé synchronized, nous évitons les erreurs de programmation simultanées dans le code.
- Lorsqu'une méthode ou un bloc est déclaré comme synchronisé, un thread a besoin d'un verrou exclusif pour entrer dans la méthode ou le bloc synchronisé. Après avoir effectué les actions nécessaires, le thread libère le verrou et vide l'opération d'écriture. De cette façon, il éliminera les erreurs de mémoire liées à l'incohérence.
Volatile à Java
Un mot-clé volatile en Java est utilisé pour rendre les classes thread-safe. Nous utilisons également le mot-clé volatile pour modifier la valeur de la variable par différents threads. Un mot clé volatile peut être utilisé pour déclarer une variable avec des types primitifs ainsi que des objets.
Dans certains cas, un mot clé volatile est utilisé comme alternative au mot clé synchronized mais notez qu'il ne remplace pas le mot clé synchronized.
Lorsqu'une variable est déclarée volatile, sa valeur n'est jamais mise en cache mais est toujours lue depuis la mémoire principale. Une variable volatile garantit la commande et la visibilité. Bien qu'une variable puisse être déclarée comme volatile, nous ne pouvons pas déclarer de classes ou de méthodes comme volatiles.
Considérez le bloc de code suivant:
class ABC{ static volatile int myvar =10; }
Dans le code ci-dessus, la variable myvar est statique et volatile. Une variable statique est partagée entre tous les objets de classe. La variable volatile réside toujours dans la mémoire principale et n'est jamais mise en cache.
Il n'y aura donc qu'une seule copie de myvar dans la mémoire principale et toutes les actions de lecture / écriture seront effectuées sur cette variable à partir de la mémoire principale. Si myvar n'était pas déclaré comme volatile, alors chaque objet thread aurait une copie différente qui entraînerait des incohérences.
Certaines des différences entre les mots clés volatils et synchronisés sont répertoriées ci-dessous.
Mot-clé volatile | Mot-clé synchronisé |
---|---|
Le mot-clé volatile est utilisé avec des variables uniquement. | Le mot-clé synchronized est utilisé avec des blocs de code et des méthodes. |
Un mot clé volatile ne peut pas bloquer le thread pour l'attente. | Le mot-clé synchronized peut bloquer le thread pour l'attente. |
Les performances des threads sont améliorées avec Volatile. | Les performances des threads se dégradent quelque peu avec synchronized. |
Les variables volatiles résident dans la mémoire principale. | Les constructions synchronisées ne résident pas dans la mémoire principale. |
Volatile synchronise une variable entre la mémoire de thread et la mémoire principale à la fois. | Le mot-clé synchronisé synchronise toutes les variables à la fois. |
Blocage à Java
Nous avons vu que nous pouvons synchroniser plusieurs threads à l'aide de mots-clés synchronized et rendre les programmes thread-safe. En synchronisant les threads, nous nous assurons que les multiples threads s'exécutent simultanément dans un environnement multi-thread.
Cependant, il arrive parfois qu'une situation se produise dans laquelle les threads ne peuvent plus fonctionner simultanément. Au lieu de cela, ils attendent sans fin. Cela se produit lorsqu'un thread attend sur une ressource et que cette ressource est bloquée par le deuxième thread.
Le deuxième thread, en revanche, attend la ressource bloquée par le premier thread. Une telle situation donne lieu à une «impasse» en Java.
Le blocage en Java est représenté à l'aide de l'image ci-dessous.
Comme nous pouvons le voir sur le diagramme ci-dessus, le thread A a verrouillé la ressource r1 et attend la ressource r2. Le thread B, en revanche, a bloqué la ressource r2 et attend r1.
Ainsi, aucun des threads ne peut terminer son exécution à moins de mettre la main sur les ressources en attente. Cette situation a entraîné une impasse où les deux threads attendent sans cesse les ressources.
Ci-dessous, un exemple de Deadlocks en Java.
public class Main { public static void main(String() args) { //define shared resources final String shared_res1 = 'Java tutorials'; final String shared_res2 = 'Multithreading'; // thread_one => locks shared_res1 then shared_res2 Thread thread_one = new Thread() { public void run() { synchronized (shared_res1) { System.out.println('Thread one: locked shared resource 1'); try { Thread.sleep(100);} catch (Exception e) {} synchronized (shared_res2) { System.out.println('Thread one: locked shared resource 2'); } } } }; // thread_two=> locks shared_res2 then shared_res1 Thread thread_two = new Thread() { public void run() { synchronized (shared_res2) { System.out.println('Thread two: locked shared resource 2'); try { Thread.sleep(100);} catch (Exception e) {} synchronized (shared_res1) { System.out.println('Thread two: locked shared resource 1'); } } } }; //start both the threads thread_one.start(); thread_two.start(); } }
Production
Dans le programme ci-dessus, nous avons deux ressources partagées et deux threads. Les deux threads tentent d'accéder aux ressources partagées une par une. La sortie montre les deux threads verrouillant une ressource chacun en attendant les autres. Créer ainsi une situation de blocage.
Bien que nous ne puissions pas empêcher complètement les situations d’impasse, nous pouvons certainement les éviter en prenant certaines mesures.
Vous trouverez ci-dessous les moyens par lesquels nous pouvons éviter les blocages en Java.
# 1) En évitant les verrous imbriqués
Avoir des verrous imbriqués est la raison la plus importante des blocages. Les verrous imbriqués sont les verrous attribués à plusieurs threads. Ainsi, nous devrions éviter de verrouiller plus d'un thread.
# 2) Utiliser la jonction de thread
Nous devrions utiliser Thread.join avec un temps maximum afin que les threads puissent utiliser le temps maximum pour l'exécution. Cela évitera un blocage qui se produit principalement lorsqu'un thread attend continuellement les autres.
# 3) Évitez le verrouillage inutile
Nous devons verrouiller uniquement le code nécessaire. Avoir des verrous inutiles pour le code peut entraîner des blocages dans le programme. Comme les blocages peuvent briser le code et entraver le déroulement du programme, nous devrions être enclins à éviter les blocages dans nos programmes.
Questions fréquemment posées
Q # 1) Qu'est-ce que la synchronisation et pourquoi est-ce important?
Répondre: La synchronisation est le processus de contrôle de l'accès d'une ressource partagée à plusieurs threads. Sans synchronisation, plusieurs threads peuvent mettre à jour ou modifier la ressource partagée en même temps, ce qui entraîne des incohérences.
Ainsi, nous devons nous assurer que dans un environnement multi-thread, les threads sont synchronisés de sorte que la manière dont ils accèdent aux ressources partagées est mutuellement exclusive et cohérente.
Q # 2) Qu'est-ce que la synchronisation et la non-synchronisation en Java?
Répondre: La synchronisation signifie qu'une construction est thread-safe. Cela signifie que plusieurs threads ne peuvent pas accéder à la construction (bloc de code, méthode, etc.) à la fois.
Les constructions non synchronisées ne sont pas thread-safe. Plusieurs threads peuvent accéder à tout moment aux méthodes ou aux blocs non synchronisés. Une classe non synchronisée populaire en Java est StringBuilder.
Q # 3) Pourquoi la synchronisation est-elle requise?
Répondre: Lorsque les processus doivent s'exécuter simultanément, nous avons besoin d'une synchronisation. C'est parce que nous avons besoin de ressources qui peuvent être partagées entre de nombreux processus.
Afin d'éviter les conflits entre les processus ou les threads pour accéder aux ressources partagées, nous devons synchroniser ces ressources afin que tous les threads aient accès aux ressources et que l'application fonctionne également correctement.
Q # 4) Comment obtenez-vous une ArrayList synchronisée?
Répondre: Nous pouvons utiliser la méthode de liste Collections.synchronized avec ArrayList comme argument pour convertir ArrayList en liste synchronisée.
Q # 5) HashMap est-il synchronisé?
merge sort c ++ exemple
Répondre: Non, HashMap n'est pas synchronisé mais HashTable est synchronisé.
Conclusion
Dans ce tutoriel, nous avons discuté en détail de la synchronisation des threads. Parallèlement, nous avons également découvert le mot-clé volatile et les blocages en Java. La synchronisation consiste en la synchronisation des processus et des threads.
Dans un environnement multithreading, nous sommes plus concernés par la synchronisation des threads. Nous avons vu ici l'approche des mots clés synchronisés de la synchronisation des threads.
Le blocage est une situation dans laquelle plusieurs threads attendent sans cesse des ressources. Nous avons vu l'exemple des blocages en Java ainsi que les méthodes pour éviter les blocages en Java.
=> Visitez ici pour apprendre Java à partir de zéro.
lecture recommandée
- Thread.Sleep () - Méthode Thread Sleep () en Java avec des exemples
- Threads Java avec méthodes et cycle de vie
- Principes de base de Java: syntaxe Java, classe Java et principaux concepts Java
- Multithreading en Java - Tutoriel avec des exemples
- Multithreading en C ++ avec des exemples
- Tutoriel JAVA pour les débutants: plus de 100 tutoriels vidéo Java pratiques
- Composants Java: plateforme Java, JDK, JRE et machine virtuelle Java
- Tutoriel Java String | Méthodes de chaîne Java avec exemples