Cet article vous apporte une introduction à l'utilisation du mot-clé synchronisé en Java (exemples de code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent le faire pour référence, j'espère. cela vous sera utile.
En programmation concurrente, le mot-clé synchronisé est un rôle courant. Nous avions l'habitude d'appeler le verrou de poids du mot-clé synchronisé, mais synchronisé a été optimisé dans JDK1.6 et des verrous biaisés et des verrous légers ont été introduits. Cet article présente comment utiliser le mot-clé synchronisé, les différences et les principes de mise en œuvre des verrous biaisés, des verrous légers et des verrous lourds.
Regardons d'abord les 4 utilisations du mot-clé synchronisé.
1. Modifier les méthodes ordinaires
private synchronized void synMethod(){ }
Cette utilisation, l'instance d'objet du verrou synchronisé.
2. Modifier les méthodes statiques
private static synchronized void synMethod(){ }
synchronisées dans ce cas, le lock est l'objet Class actuel.
3. Bloc de méthode synchronisé
private void synMethod1(){ synchronized(this){ } } private void synMethod2(){ synchronized(ThreadTest.class){ } }
Verrouiller l'instance d'objet dans synMethod1 ; synMethod2 est l'objet Class actuel.
Réintroduire le principe du verrouillage
Avant d'introduire le principe du verrouillage, commençons par connaître l'en-tête de l'objet Java Mark Word, en prenant 32 bits à titre d'exemple.
État de verrouillage |
25 bits |
4 bits |
1 bit |
2 bits |
||
|
23 bits |
2 bits |
S'il est biaisé en faveur du verrouillage |
Drapeau de verrouillage |
||
Verrouillage léger |
Pointeur vers l'enregistrement de verrouillage dans la pile |
0 |
||||
Verrouillage lourd |
Pointeur vers mutex (verrouillage lourd) |
10 |
||||
GCMarque |
Vide |
11 |
||||
Verrouillage de biais |
ThreadID |
Époque | Âge de génération d'objet |
1 |
01 |
|
Sans verrouillage |
hashCode de l'objet | Âge de génération d'objet |
0 |
01 |
Le tableau ci-dessus décrit les informations stockées dans l'en-tête de l'objet lorsque l'objet est dans chaque état de verrouillage.
1. Verrouillage biaisé
Dans l'environnement réel, lorsqu'un thread accède à un bloc synchronisé, si aucun autre thread n'est en compétition pour le verrou, et Le même thread acquiert le verrou plusieurs fois, c'est-à-dire qu'un seul thread exécute le code de synchronisation. Dans ce cas, si le thread est bloqué à chaque fois, cela signifie un gaspillage des performances du processeur. Dans ce cas, la notion de verrouillage biaisé est introduite.
Accéder au bloc de code synchronisé
Déterminez si l'ID de thread stocké dans l'en-tête de l'objet Mark Word pointe vers le thread actuel. Si tel est le cas, cela indique que le verrou actuel est réentrant. Il n'est pas nécessaire d'obtenir le verrou et d'exécuter directement la synchronisation. code
Sinon, essayez d'utiliser l'algorithme CAS pour mettre à jour l'ID du fil dans l'en-tête de l'objet.
Obtient avec succès le verrou et exécute le code de synchronisation. L'échec de la mise à jour indique qu'il existe une concurrence de verrouillage. Attendez le point de sécurité global, suspendez le thread qui possède le verrou biaisé et choisissez de mettre à niveau le verrou biaisé vers un verrou léger ou de le définir sur aucun verrou en fonction de l'indicateur de verrouillage dans le fichier. en-tête d'objet.
Vous pouvez utiliser -XX:-userBiasedLocking=false pour désactiver l'optimisation du verrouillage biaisé JVM et entrer le verrouillage léger directement par défaut.
2. Verrouillage léger
Bloc de code de synchronisation d'accès , créez d'abord une zone d'enregistrement de verrouillage (Lock Record) dans la pile de threads du thread actuel.
Copiez l'en-tête de l'objet Mark Word dans l'enregistrement de verrouillage.
Utilisez CAS pour essayer de mettre à jour le pointeur de fil de discussion dans l'en-tête de l'objet Marquez Word vers un pointeur vers le fil de discussion actuel
Si la mise à jour est réussi, vous obtiendrez un verrou léger.
La mise à jour a échoué, vérifiez si le pointeur dans Mark Word pointe vers le fil de discussion actuel.
Si oui, cela signifie la réentrée du verrouillage. Exécuter le bloc de code synchronisé
Sinon, cela signifie qu'il y a de la concurrence en ce moment. Les verrous légers doivent être étendus aux verrous de poids.
3. Verrouillage du poids
Le verrouillage du poids est implémenté en fonction du moniteur d'objet (Moniteur).
Lorsqu'un thread exécute du code de synchronisation, il doit appeler une instruction Monitor.enter. Une fois l’exécution terminée, appelez l’instruction Monitor.exit. On peut voir ici que le moniteur est exclusif. Un seul thread peut entrer avec succès à un moment donné, et les autres threads ne peuvent être bloqués que dans la file d'attente. Ce verrou à poids est donc très coûteux à exploiter.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!