La méthode de synchronisation la plus basique en Java consiste à utiliser le mot-clé synchronisé pour contrôler l'accès simultané à une méthode. Chaque méthode déclarée avec le mot-clé synchronisé est une section critique. En Java, une seule section critique du même objet est accessible en même temps.
Les méthodes statiques ont un comportement différent. Les méthodes statiques déclarées avec le mot-clé synchronisé ne sont accessibles que par un seul thread d'exécution à la fois, mais d'autres threads peuvent accéder aux méthodes synchronisées non statiques de cet objet. Vous devez être très prudent à ce sujet car deux threads peuvent accéder simultanément à deux méthodes synchronisées différentes d'un objet, c'est-à-dire que l'une d'elles est une méthode synchronisée statique et l'autre est une méthode synchronisée non statique. Si les deux méthodes modifient les mêmes données, une erreur d'incohérence des données se produira. La syntaxe du
bloc synchronisé est la suivante :
public void method() { synchronized(表达式) { } }
Le mot-clé synchronisé a deux utilisations, l'une est utilisée uniquement dans la définition des méthodes, et l'autre est un bloc synchronisé non seulement. pouvons-nous utiliser synchronisé pour synchroniser une variable d'objet. Vous pouvez également utiliser synchronisél pour synchroniser les méthodes statiques et non statiques dans une classe.
Le premier : Synchronisation des méthodes non statiques
D'après la syntaxe Java pertinente, nous pouvons savoir que l'utilisation du mot-clé synchronisé pour définir les méthodes verrouillera les méthodes statiques et les méthodes non statiques définies en utilisant le mot-clé synchroniezd dans la méthode class. Static, mais c'est un peu difficile à comprendre. Si vous souhaitez qu'un bloc synchronisé obtienne un tel effet, il n'est pas difficile de comprendre pourquoi cet effet se produit si vous utilisez synchronisé pour tout verrouiller. méthodes non statiques synchronisées dans la classe, il vous suffit d'utiliser Ceci est passé dans le bloc synchronisé en tant que paramètre du bloc synchronisé Le code est le suivant :
public class Test { public void method1() { synchronized(this) { } } public synchronized void method2() { } } public class Test { public void method1() { synchronized(this) { } } public synchronized void method2() { } }
Dans le code ci-dessus, méthode1. utilise le bloc synchronisé et la méthode method2 utilise le mot-clé synchronisé pour définir la méthode. Si vous utilisez Lorsque vous utilisez la même instance de Test, tant qu'une de ces deux méthodes est en cours d'exécution, les autres méthodes seront bloquées car elles n'ont pas obtenu. le verrou de synchronisation. En plus de l'utiliser comme paramètre du bloc synchronisé, vous pouvez également utiliser Test.this comme paramètre du bloc synchronisé pour obtenir le même effet.
Dans les blocs synchronisés utilisés dans les classes internes, 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 et les méthodes non statiques de la classe externe peuvent également être synchronisées. Si vous ajoutez une méthode méthode3 dans la classe interne, vous pouvez également la synchroniser avec les deux méthodes dans Test. Le code est le suivant :
public class Test { class InnerClass { public void method3() { synchronized(Test.this){ } } } } public class Test { class InnerClass { public void method3() { synchronized(Test.this){ } } } }
La méthode méthode3 ci-dessus d'InnerClass et la méthode méthode1 et méthode2. de Test ne peut être synchronisé qu'en même temps. Il peut y avoir un moyen de le faire.
Que le bloc synchronisé soit exécuté correctement ou quitte le bloc synchronisé en raison d'une exception due à une erreur de programme, le verrou de synchronisation détenu par le bloc synchronisé actuel sera automatiquement libéré, il n'y a donc pas lieu de s'inquiéter du verrou de synchronisation problème lors de l’utilisation du bloc synchronisé.
2. Synchronisation des méthodes statiques
Puisque l'instance d'objet n'est pas nécessairement créée lors de l'appel de la méthode statique, vous ne pouvez donc pas l'utiliser pour synchroniser la méthode statique, mais vous devez utiliser l'objet Class pour synchroniser la méthode statique. Le code est le suivant :
public class Test{ pubic static void method1(){ synchronized(Test.class){ } } public static synchronized void method2(){ } } public class Test{ pubic static void method1(){ synchronized(Test.class){ } } public static synchronized void method2(){ } }
Lors de la synchronisation des méthodes statiques, vous pouvez utiliser la classe de champ statique de la classe pour obtenir l'objet de classe. Dans l'exemple ci-dessus, les méthodes méthode1 et méthode2 n'ont qu'une seule méthode pour. exécuter. En plus d'utiliser le champ de classe, vous pouvez obtenir l'objet de classe. , vous pouvez également obtenir l'objet de classe via la méthode getClass() de l'instance. Le code est le suivant :
public class Test{ public static Test test; public Test(){ test=this; } public static void method1(){ synchronized(test.getClass()){ } } } public class Test{ public static Test test; public Test(){ test=this; } public static void method1(){ synchronized(test.getClass()){ } } }
. Dans le code ci-dessus, nous obtenons une instance de Test via un objet statique public et passons la méthode getClass de l'instance pour obtenir un objet de classe (notez que toutes les instances d'une classe obtiennent le même objet Class via la méthode getClass). Nous pouvons également synchroniser les méthodes statiques de différentes classes via la classe. Le code est le suivant :
public class Test1{ public static void method1(){ synchronized(Test.class){ } } } public class Test1{ public static void method1(){ synchronized(Test.class){ } } }
Remarque : lors de l'utilisation de blocs synchronisés pour synchroniser les méthodes, les méthodes non statiques peuvent être synchronisées via cela, tandis que les méthodes statiques. doit utiliser un objet de classe pour synchroniser, mais les méthodes non statiques peuvent également synchroniser des méthodes statiques en utilisant la classe. 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 blocs synchronisés.
Remarque
Le mot-clé synchronisé réduira les performances de l'application, il ne peut donc être utilisé que dans des scénarios simultanés sur des méthodes qui doivent modifier les données partagées. Si plusieurs threads accèdent à la même méthode synchronisée, un seul thread peut y accéder et les autres threads attendront. Si la déclaration de méthode n'utilise pas le mot-clé synchronisé, tous les threads peuvent exécuter la méthode en même temps, réduisant ainsi la durée totale d'exécution. Si l’on sait qu’une méthode ne sera pas appelée par plus d’un thread, il n’est pas nécessaire de la déclarer avec le mot-clé synchronisé.
Les méthodes déclarées comme synchronisées peuvent être appelées de manière récursive. Lorsqu'un thread accède à la méthode synchronisée d'un objet, il peut également appeler d'autres méthodes synchronisées de l'objet, y compris la méthode en cours d'exécution, sans avoir à avoir à nouveau accès à cette méthode.
我们可以通过synchronized关键字来保护代码块(而不是整个方法)的访问。应该这样利用synchronized关键字:方法的其余部分保持在synchronized代码块之外,以获取更好的性能。临界区(即同一时间只能被一个线程访问的代码块)的访问应该尽可能的短。例如在获取一幢楼人数的操作中,我们只使用synchronized关键字来保护对人数更新的指令,并让其他操作不使用共享数据。当这样使用synchronized关键字时,必须把对象引用作为传入参数。同一时间只有一个线程被允许访问这个synchronized代码。通常来说,我们使用this关键字来引用正在执行的方法所属的对象:
synchronized(this){ //Java code }
更多Java中synchronized关键字修饰方法同步的用法详解相关文章请关注PHP中文网!