Synchronisation en Java
Qu'est-ce que le Synchronisation en Java?
In Java, la synchronisation fait rรฉfรฉrence ร la capacitรฉ de contrรดler l'accรจs de plusieurs threads ร n'importe quelle ressource partagรฉe. C'est une option idรฉale lorsque nous souhaitons autoriser un seul thread ร accรฉder ร la ressource partagรฉe.
Cette approche d'exรฉcution est gรฉnรฉralement appelรฉe programmation ยซ asynchrone ยป. Il existe รฉgalement des threads sur ces processeurs, qui sont des processus lรฉgers capables d'exรฉcuter des instructions simultanรฉment.
Types d' Synchronisation
Il existe deux types de mรฉthodes de synchronisation dans Java:
1) Synchronisation des processus
2) Synchronisation des threads.
รtudions Thread et Synchronisation des processus en dรฉtail.
Synchronisation des processus : Il gรจre la synchronisation entre les programmes. Par exemple, des programmes tels que `Microsoft Word` et `Acrobat reader` s'exรฉcutent en tant que processus individuels.
Synchronisation des threads : L'exรฉcution simultanรฉe de la ressource critique par deux ou plusieurs threads est appelรฉe Thread. Synchronisation. Vous pouvez รชtre regroupรฉs davantage pour une communication mutuellement exclusive et inter-thread.
Qu'est-ce que le verrouillage Java?
Verrouiller Java est construit autour dโune entitรฉ interne appelรฉe moniteur ou verrou. Tous les objets sont associรฉs ร un verrou. Ainsi, le thread qui a besoin d'un accรจs cohรฉrent aux champs d'un objet doit acquรฉrir le verrou de l'objet avant d'y accรฉder, et il libรจre le verrou lorsque le travail est terminรฉ. Cela garantit qu'un seul thread accรจde aux donnรฉes partagรฉes ร la fois.
Programme multithread avec synchronisation
Un programme multithread est une mรฉthode ou un bloc protรฉgรฉ des interfรฉrences d'autres threads partageant la mรชme ressource indiquรฉe ร l'aide du mot-clรฉ ยซ synchronized ยป.
Utiliser la mรฉthode synchronisรฉe
Toute mรฉthode dรฉclarรฉe comme synchronisรฉe est appelรฉe mรฉthode synchronisรฉe. Il est รฉgalement utilisรฉ pour verrouiller un objet pour toute ressource partagรฉe. Ainsi, lorsqu'un thread invoque une mรฉthode synchronisรฉe. Il prend automatiquement possession du verrou de cet objet et le libรจre lorsqu'il a terminรฉ sa tรขche.
ร noter: Le mot-clรฉ synchronisรฉ ne peut pas fonctionner avec les classes et les variables. Seules les mรฉthodes et les blocs peuvent รชtre utilisรฉs avec le mot-clรฉ.
Pourquoi utiliser le SyncMรฉthode hronisรฉe ?
- Il est utilisรฉ pour verrouiller un objet pour toutes les ressources partagรฉes.
- L'objet obtient le verrou chaque fois que la mรฉthode synchronisรฉe est appelรฉe.
- Le verrou ne se libรจre que lorsque le fil a terminรฉ sa fonction
syntaxe:
Acess_modifiers synchronized return_type method_name (Method_Parameters) {
}
class MathService {
synchronized void getSumOfArray(int[] numbers) {
int sum = 0;
for (int number : numbers) {
System.out.println(Thread.currentThread()
.getName()
+ " adds "
+ sum + " to "
+ number + " to get -> "
+ (sum += number));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Synchronization {
public static void main(String[] args) {
MathService mathService = new MathService();
Thread threadOne = new Thread(() ->
mathService.getSumOfArray(new int[]{10, 11, 12}));
Thread threadTwo = new Thread(() ->
mathService.getSumOfArray(new int[]{20, 21, 22}));
threadOne.start();
threadTwo.start();
}
}
Explication de Code:
Exรฉcutez cet exemple et observez que le thread ยซ 0 ยป obtient d'abord le verrou de l'objet ยซ mathService ยป et utilise ce verrou exclusivement jusqu'ร ce qu'il ait terminรฉ son exรฉcution. Les threads ยซ 0 ยป et ยซ 1 ยป ne sont pas entrelacรฉs dans ce code. Le rรฉsultat est comme indiquรฉ ci-dessous.
Sortie :
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Utiliser un bloc synchronisรฉ
Supposons que vous ne souhaitiez pas synchroniser l'intรฉgralitรฉ de la mรฉthode. Au lieu de cela, vous souhaitez synchroniser quelques lignes de code. ร ce moment-lร , SyncLe bloc horronisรฉ a aidรฉ ร synchroniser ce qui a รฉtรฉ sรฉlectionnรฉ Java code. SyncLes verrous de mรฉthode synchrones sont accessibles sur la mรฉthode, tandis que les verrous de bloc synchronisรฉs sont accessibles sur l'objet.
class MathService {
void getSumOfArray(int[] numbers) {
synchronized (this){
int sum = 0;
for (int number : numbers) {
System.out.println(Thread.currentThread()
.getName()
+ " adds "
+ sum + " to "
+ number + " to get -> "
+ (sum += number));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class Synchronization {
public static void main(String[] args) {
MathService mathService = new MathService();
Thread threadOne = new Thread(() ->
mathService.getSumOfArray(new int[]{10, 11, 12}));
Thread threadTwo = new Thread(() ->
mathService.getSumOfArray(new int[]{20, 21, 22}));
threadOne.start();
threadTwo.start();
}
}
Code Explication:
En exรฉcutant ce code, vous remarquerez qu'il fonctionne sans aucune interfรฉrence. Dans la mรฉthode synchronisรฉe, le verrou est appliquรฉ par la mรฉthode, mais dans le bloc synchronisรฉ, le verrou est appliquรฉ par l'objet. Assurez-vous que la sortie est comme indiquรฉ ci-dessous.
Sortie :
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Explication du code:
Lorsque vous exรฉcutez ce code, vous remarquerez quโil fonctionne sans interfรฉrence, ce ร quoi nous nous attendions. Dans la mรฉthode synchronisรฉe, le verrou est appliquรฉ par la mรฉthode, mais dans la mรฉthode de bloc synchronisรฉ, le verrou est appliquรฉ par l'objet.
Utiliser la synchronisation statique
In Java Synchronisation : s'il y a plus d'un objet, deux threads peuvent acquรฉrir les verrous et entrer dans un bloc synchronisรฉ ou un bloc, avec un verrou sรฉparรฉ pour chaque objet. Pour รฉviter cela, une synchronisation statique peut รชtre utilisรฉe. Syncles mots-clรฉs hronisรฉs seront utilisรฉs avant les mรฉthodes statiques.
ร noter: Dans la synchronisation statique, le verrouillage de l'accรจs concerne la classe, et non l'objet et la mรฉthode.
Code pour illustrer le problรจme du verrouillage de plusieurs objets
class MathService {
synchronized void getSumOfArray(int[] numbers) {
int sum = 0;
for (int number : numbers) {
System.out.println(Thread.currentThread()
.getName()
+ " adds "
+ sum + " to "
+ number + " to get -> "
+ (sum += number));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Synchronization {
public static void main(String[] args) {
MathService mathService = new MathService();
MathService mathService1 = new MathService();
Thread threadOne = new Thread(() ->
mathService.getSumOfArray(new int[]{10, 11, 12}));
Thread threadTwo = new Thread(() ->
mathService.getSumOfArray(new int[]{20, 21, 22}));
Thread threadThree = new Thread(() ->
mathService1.getSumOfArray(new int[]{10, 11, 12}));
Thread threadFour = new Thread(() ->
mathService1.getSumOfArray(new int[]{20, 21, 22}));
threadOne.start();
threadTwo.start();
threadThree.start();
threadFour.start();
}
}
Explication du code:
Lorsque nous crรฉons une autre instance de `MathService`, nous introduisons des interfรฉrences dans les threads car ils seront entrelacรฉs avec les deux objets. Notez que le thread ยซ 0 ยป et le thread ยซ 2 ยป sont entrelacรฉs avec les deux objets, tandis que les threads ยซ 1 ยป et ยซ 3 ยป sont entrelacรฉs avec les deux objets.
Sortie :
Thread-0 adds 0 to 10 to get -> 10 Thread-2 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-2 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-2 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-3 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-3 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63 Thread-3 adds 41 to 22 to get -> 63
Mรชme code en utilisant la mรฉthode statique synchronisรฉe
class MathService {
synchronized static void getSumOfArray(int[] numbers) {
int sum = 0;
for (int number : numbers) {
System.out.println(Thread.currentThread()
.getName()
+ " adds "
+ sum + " to "
+ number + " to get -> "
+ (sum += number));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Synchronization {
public static void main(String[] args) {
MathService mathService = new MathService();
MathService mathService1 = new MathService();
Thread threadOne = new Thread(() ->
mathService.getSumOfArray(new int[]{10, 11, 12}));
Thread threadTwo = new Thread(() ->
mathService.getSumOfArray(new int[]{20, 21, 22}));
Thread threadThree = new Thread(() ->
mathService1.getSumOfArray(new int[]{10, 11, 12}));
Thread threadFour = new Thread(() ->
mathService1.getSumOfArray(new int[]{20, 21, 22}));
threadOne.start();
threadTwo.start();
threadThree.start();
threadFour.start();
}
}
Exรฉcutez le code ci-dessus et notez que nous avons maintenant รฉliminรฉ les interfรฉrences de thread. La sortie du code est prรฉsentรฉe ci-dessous.
Sortie :
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-3 adds 0 to 20 to get -> 20 Thread-3 adds 20 to 21 to get -> 41 Thread-3 adds 41 to 22 to get -> 63 Thread-2 adds 0 to 10 to get -> 10 Thread-2 adds 10 to 11 to get -> 21 Thread-2 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Avantages de l'utilisation de la synchronisation
Voici les avantages de travailler avec des applications simultanรฉes :
- Lโobjectif principal de la synchronisation dans Java est d'empรชcher les donnรฉes incohรฉrentes en empรชchant les interfรฉrences entre les threads.
- Le mot clรฉ synchronisรฉ dans Java fournit un verrouillage, qui garantit un accรจs mutuellement exclusif ร la ressource partagรฉe et empรชche la course aux donnรฉes.
- Cela empรชche รฉgalement la rรฉorganisation des instructions de code par le compilateur, ce qui peut provoquer un subtil problรจme de concurrence si nous n'utilisons pas de mots-clรฉs volatils ou synchronisรฉs.
- SyncLe mot-clรฉ hronized lit les donnรฉes de la mรฉmoire principale plutรดt que du cache et lorsqu'il libรจre le verrou.
- Il supprime รฉgalement les opรฉrations d'รฉcriture de la mรฉmoire principale, รฉliminant ainsi les erreurs d'incohรฉrence de la mรฉmoire.
Inconvรฉnients de SyncMรฉcanisme d'hronisation
SyncLes mรฉcanismes de hronisation ont des performances mรฉdiocres.
Par exemple
- Supposons quโil existe cinq processus : A1, A2, A3, A4 et A5.
- Ils attendent que les ressources partagรฉes accรจdent ร un thread ร la fois.
- Tous les processus restent en attente, donc le dernier dans la file d'attente doit attendre que tous les autres processus soient terminรฉs.
Rรฉsumรฉ
- SyncL'hronisation fait rรฉfรฉrence ร la possibilitรฉ de contrรดler l'accรจs de plusieurs threads ร n'importe quelle ressource partagรฉe.
- Java dispose de deux types de mรฉthodes de synchronisation : 1) Synchronisation des processus et 2) Synchronisation des threads.
- Verrouiller Java est construit autour dโune entitรฉ interne appelรฉe moniteur ou verrou.
- Un programme multithread est une mรฉthode ou un bloc protรฉgรฉ des interfรฉrences d'autres threads partageant la mรชme ressource indiquรฉe ร l'aide du mot-clรฉ ยซ synchronized ยป.
- Toute mรฉthode dรฉclarรฉe comme synchronisรฉe est appelรฉe mรฉthode synchronisรฉe.
- In Java, les verrous de mรฉthode synchronisรฉs sont accessibles sur la mรฉthode, tandis que les verrous de bloc synchronisรฉs sont accessibles sur l'objet.
- Dans la synchronisation statique, le verrouillage de l'accรจs concerne la classe, et non l'objet et la mรฉthode.
- Lโobjectif principal de la synchronisation dans Java est d'empรชcher les donnรฉes incohรฉrentes en empรชchant les interfรฉrences entre les threads.
- Le plus gros inconvรฉnient de cette mรฉthode est que tous les processus sont maintenus en attente, de sorte que le dernier dans la file d'attente doit attendre que tous les autres processus soient terminรฉs.
