Le mot-clé synchronisé a deux utilisations. La première est de l'utiliser directement dans la définition de la méthode comme introduit dans l'article "Utiliser le mot-clé Synchronized pour synchroniser les méthodes de classe". Un autre type est le bloc synchronisé. Nous ne pouvons pas seulement synchroniser une variable objet via des blocs synchronisés. Vous pouvez également utiliser des blocs synchronisés pour synchroniser les méthodes statiques et non statiques dans une classe.
La syntaxe du bloc synchronisé est la suivante :
Copiez le code comme suit :
méthode public void()
{
… …
synchronisé(expression)
{
… …
}
}
1. Synchronisation des méthodes de classe non statiques
D'après l'article « Utilisation du mot-clé Synchronized pour synchroniser les méthodes de classe », nous savons que l'utilisation du mot-clé synchronisé pour définir des méthodes verrouillera toutes les méthodes statiques ou non statiques définies à l'aide du mot-clé synchronzied dans la classe, mais ce n'est pas facile à comprendre. Si vous utilisez des blocs synchronisés pour obtenir le même effet, il n'est pas difficile de comprendre pourquoi cet effet se produit. Si vous souhaitez utiliser un bloc synchronisé pour verrouiller toutes les méthodes non statiques synchronisées dans une classe, vous devez l'utiliser comme paramètre du bloc synchronisé et le transmettre au pays du bloc synchronisé. Le code est le suivant :
Synchronisez les méthodes non statiques via des blocs synchronisés
Copiez le code comme suit :
classe publique SyncBlock
{
méthode vide publique1()
{
synchronisé(this) // Équivaut à l'utilisation du mot-clé synchronisé sur la méthode method1
{
… …
}
}
méthode vide publique2()
{
synchronisé(this) // Équivaut à l'utilisation du mot-clé synchronisé pour la méthode method2
{
… …
}
}
méthode vide synchronisée publique3()
{
… …
}
}
Dans le code ci-dessus, les blocs synchronisés sont utilisés dans les méthodes method1 et method2. La méthode method3 de la ligne 017 utilise toujours le mot-clé synchronisé pour définir la méthode. Lors de l'utilisation de la même instance de classe SyncBlock, tant qu'une des trois méthodes est en cours d'exécution, les deux autres méthodes seront bloquées car le verrou de synchronisation n'est pas obtenu. Pour obtenir le même effet que le mot-clé synchronisé lors de l'utilisation du bloc synchronisé, tout le code doit être écrit dans le bloc synchronisé, sinon tout le code de la méthode actuelle ne sera pas synchronisé avec les autres méthodes.
En plus de l'utiliser comme paramètre du bloc synchronisé, vous pouvez également utiliser SyncBlock.this comme paramètre du bloc synchronisé pour obtenir le même effet.
Lors de l'utilisation du bloc synchronisé dans la méthode de la classe interne (InnerClass), cela représente uniquement la classe interne et n'a rien à voir avec la classe externe (OuterClass). Mais les méthodes non statiques de la classe interne peuvent être synchronisées avec les méthodes non statiques de la classe externe. Par exemple, ajoutez une méthode method4 à la classe interne InnerClass et synchronisez la méthode method4 avec les trois méthodes de SyncBlock. Le code est le suivant :
Synchronisez les méthodes non statiques de la classe interne avec les méthodes non statiques de la classe externe
Copiez le code comme suit :
classe publique SyncBlock
{
… …
classeInnerClass
{
méthode public void4()
{
synchronisé (SyncBlock.this)
{
… …
}
}
}
… …
}
Dans la nouvelle version de la classe SyncBlock ci-dessus, la méthode méthode 4 de la classe InnerClass est synchronisée avec les trois autres méthodes de la classe SyncBlock. Par conséquent, une seule méthode parmi les quatre méthodes méthode1, méthode2, méthode3 et méthode4 peut être exécutée. en même temps.
Que le bloc synchronisé soit exécuté normalement ou quitte le bloc synchronisé anormalement en raison d'une erreur de programme, le verrou de synchronisation détenu par le bloc synchronisé actuel sera automatiquement libéré. Par conséquent, vous n'avez pas à vous soucier de la libération des verrous de synchronisation lors de l'utilisation de blocs synchronisés.
2. Synchronisation des méthodes de classe statique
Car lors de l’appel d’une méthode statique, l’instance d’objet n’est pas nécessairement créée. Par conséquent, vous ne pouvez pas l'utiliser pour synchroniser des méthodes statiques, mais vous devez utiliser des objets Class pour synchroniser des méthodes statiques. Le code est le suivant :
Synchronisez les méthodes statiques via des blocs synchronisés
Copiez le code comme suit :
classe publique StaticSyncBlock
{
méthode vide statique publique1()
{
synchronisé (StaticSyncBlock.class)
{
… …
}
}
méthode vide synchronisée statique publique2()
{
… …
}
}
Lors de la synchronisation de méthodes statiques, vous pouvez utiliser la classe de champ statique de la classe pour obtenir l'objet Class. Dans l'exemple ci-dessus, une seule méthode de méthode1 et méthode2 peut être exécutée en même temps. En plus d'utiliser le champ class pour obtenir l'objet Class, vous pouvez également utiliser la méthode getClass de l'instance pour obtenir l'objet Class. Le code de l'exemple ci-dessus peut être modifié comme suit :
Utilisez la méthode getClass pour obtenir l'objet Class
Copiez le code comme suit :
classe publique StaticSyncBlock
{
instance publique statique de StaticSyncBlock ;
public StaticSyncBlock()
{
exemple = ceci ;
}
méthode vide statique publique1()
{
synchronisé(instance.getClass())
{
}
}
}
Dans le code ci-dessus, une instance de la classe StaticSyncBlock est obtenue via une instance statique publique et l'objet Class est obtenu via la méthode getClass de cette instance (toutes les instances d'une classe obtiennent le même objet Class via la méthode getClass, par conséquent, appelant n'importe quelle méthode getClass d'une instance peut être utilisée). Nous pouvons également synchroniser les méthodes statiques de différentes classes via des objets Class, comme la méthode statique de la classe Test et les deux méthodes statiques de la classe StaticSyncBlock. Le code est le suivant :
La méthode méthode de la classe Test est synchronisée avec les méthodes méthode1 et méthode2 de la classe StaticSyncBlock.
Copiez le code comme suit :
Test de classe publique
{
méthode publique static void()
{
synchronisé (StaticSyncBlock.class)
{
}
}
}
Remarque : lors de l'utilisation de méthodes de classe de synchronisation de blocs synchronisés, les méthodes non statiques peuvent l'utiliser pour se synchroniser, tandis que les méthodes statiques doivent utiliser l'objet Class pour se synchroniser. Ils ne s’influencent pas mutuellement. Bien entendu, vous pouvez également utiliser des objets Class dans des méthodes non statiques pour synchroniser les méthodes statiques. Mais cela ne peut pas être utilisé dans les méthodes statiques pour synchroniser les méthodes non statiques. Ceci doit être noté lors de l’utilisation de méthodes de classe de synchronisation de blocs synchronisés.