Maison Java javaDidacticiel Une explication de l'utilisation de base du mot-clé synchronisé dans la programmation multithread Java

Une explication de l'utilisation de base du mot-clé synchronisé dans la programmation multithread Java

Jan 05, 2017 pm 03:48 PM

Dans la programmation multithread, le problème le plus critique et le plus préoccupant devrait être la synchronisation. C'est un point difficile et aussi le cœur.
Des versions synchronisées et volatiles de jdk à l'interface Lock dans le package java.util.concurrent.locks fourni dans jdk 1.5 (implémenté avec ReadLock, WriteLock, ReentrantLock), l'implémentation du multi-threading mûrit également étape par étape. changement radical.

La synchronisation, par quel mécanisme est-elle contrôlée ? La première réaction est les verrous. Vous auriez dû y être exposé lors de l’apprentissage des systèmes d’exploitation et des bases de données. Dans un programme Java multithread, lorsque plusieurs programmes sont en compétition pour la même ressource, afin d'éviter toute corruption des ressources, un verrou d'objet est attribué au premier thread pour accéder à la ressource, et les suivants doivent attendre la libération du verrouillage d'objet.

Oui, la synchronisation des threads Java concerne principalement l'utilisation des ressources partagées.

Commençons par comprendre quelques ressources partagées des threads.
Comprenez à partir de la JVM quels threads partagent des données qui doivent être coordonnées :
Variables d'instance stockées dans le tas ; la zone méthode.

Lorsque la machine virtuelle Java charge une classe, chaque objet ou classe sera associé à un moniteur pour protéger les variables d'instance ou les variables de classe de l'objet bien sûr, si l'objet n'a pas de variables d'instance ou de classe, sans variables, le moniteur ne surveille rien.

Afin d'obtenir l'exclusivité mutuelle du moniteur mentionné ci-dessus, la machine virtuelle associe un verrou (également appelé verrou invisible) à chaque objet ou classe. Laissez-moi vous expliquer ici, les verrous de classe sont également obtenus via l'objet. locks. Ceci est obtenu car lorsqu'une classe est chargée, la JVM crée une instance de java.lang.Class pour chaque classe ; par conséquent, lorsque l'objet est verrouillé, l'objet de classe de cette classe est également verrouillé.

De plus, un thread peut verrouiller un objet plusieurs fois, ce qui correspond à plusieurs releases ; c'est un calculateur de verrou fourni par la JVM pour chaque verrou d'objet. Le dernier verrou est ajouté 1, le décrément correspondant est 1. , et lorsque la valeur de la calculatrice est 0, elle est libérée. Ce verrou d'objet est utilisé par le moniteur à l'intérieur de la JVM et est automatiquement généré par la JVM. Tous les programmeurs n'ont pas besoin de l'ajouter eux-mêmes.

Après avoir présenté le principe de synchronisation de Java, parlons d'abord de l'utilisation de synchronisé, et d'autres synchronisations seront introduites dans les chapitres suivants.

Essayons d'abord de donner un exemple.

package thread_test; 
  
/** 
 * 测试扩展Thread类实现的多线程程序 
 * 
 */
public class TestThread extends Thread{  
  private int threadnum; 
  
  public TestThread(int threadnum) {  
    this.threadnum = threadnum;  
  } 
    
  @Override
  public synchronized void run() {  
    for(int i = 0;i<1000;i++){  
          System.out.println("NO." + threadnum + ":" + i ); 
    } 
    }  
    
    public static void main(String[] args) throws Exception {  
      for(int i=0; i<10; i++){ 
          new TestThread(i).start(); 
          Thread.sleep(1); 
      } 
    }  
}
Copier après la connexion

Résultats d'exécution :

NO.0:887 
NO.0:888 
NO.0:889 
NO.0:890 
NO.0:891 
NO.0:892 
NO.0:893 
NO.0:894 
NO.7:122 
NO.7:123 
NO.7:124
Copier après la connexion

Ce qui précède n'est qu'un extrait pour illustrer un problème.
Les enfants prudents constateront que NO.0:894 est suivi de NO.7:122, ce qui signifie qu'il ne commence pas de 0 à 999.
On dit que synchronisé peut implémenter des méthodes synchronisées ou des blocs synchronisés. Pourquoi cela ne peut-il pas être fait ici ?

Analysons d'abord le mécanisme de synchronisation. La synchronisation est réalisée via des verrous. Donc, dans l'exemple ci-dessus, quels objets ou classes sont verrouillés ? Il contient deux variables, l'une est i et l'autre est threadnum ; i est interne à la méthode et threadnum est privé.
Apprenons-en davantage sur le mécanisme de fonctionnement synchronisé :
Dans un programme Java, lors de l'utilisation d'un bloc synchronisé ou d'une méthode synchronisée, cette zone est marquée pour la surveillance lorsque la JVM traite le programme, lorsqu'un programme entre dans le programme ; zone de surveillance, l'objet ou la classe est automatiquement verrouillé.

Donc, dans l'exemple ci-dessus, une fois le mot-clé synchronisé utilisé, qu'est-ce qui est verrouillé ?
Lorsqu'une méthode synchronisée est utilisée, l'objet d'instance lui-même qui appelle la méthode est verrouillé en tant que verrou d'objet. Dans cet exemple, 10 threads ont leurs propres objets de classe TestThread créés par eux-mêmes, donc le verrou d'objet acquis est également leur propre verrou d'objet et n'a rien à voir avec les autres threads.

Pour implémenter le verrouillage de méthode, un objet partagé doit être verrouillé.

Modifiez l'exemple ci-dessus et jetez un autre regard :

package thread_test; 
  
/** 
 * 测试扩展Thread类实现的多线程程序 
 * 
 */
public class TestThread extends Thread{  
  private int threadnum; 
  private String flag;  //标记 
    
  public TestThread(int threadnum,String flag) {  
       this.threadnum = threadnum;  
        this.flag = flag; 
    } 
    
  @Override
    public void run() {  
    synchronized(flag){ 
      for(int i = 0;i<1000;i++){  
              System.out.println("NO." + threadnum + ":" + i ); 
          }  
    } 
    }  
  
    public static void main(String[] args) throws Exception {  
      String flag = new String("flag"); 
      for(int i=0; i<10; i++){ 
          new TestThread(i,flag).start(); 
          Thread.sleep(1); 
      } 
    }  
}
Copier après la connexion

Un drapeau partagé est également ajouté. Synchronisez ensuite le drapeau via le bloc synchronisé ; cela remplit les conditions de verrouillage de l'objet partagé.
Oui, les résultats en cours sont arrivés dans l'ordre.

Grâce au bloc synchronisé, spécifiez l'acquisition du verrouillage de l'objet pour atteindre l'objectif de synchronisation. Existe-t-il une autre méthode pouvant être obtenue grâce à la méthode synchronisée ?

Selon le principe de synchronisation : Si vous pouvez obtenir un verrou d'objet partagé ou un verrou de classe, la synchronisation peut être réalisée. Alors pouvons-nous y parvenir en partageant un verrou de classe ?

Oui, nous pouvons utiliser des méthodes de synchronisation statiques. Selon les caractéristiques des méthodes statiques, elles ne peuvent être appelées que par l'objet de classe lui-même et ne peuvent pas être appelées en instanciant un objet de classe. Ensuite, si le verrou de cette méthode statique est obtenu, ce verrou de classe est obtenu, et ces verrous de classe sont tous des verrous de classe TestThread, et l'objectif d'obtenir le verrou de classe partagé est atteint.

Le code d'implémentation est le suivant :

package thread_test; 
  
/** 
 * 测试扩展Thread类实现的多线程程序 
 * 
 * @author ciding 
 * @createTime Dec 7, 2011 9:37:25 AM 
 * 
 */
public class TestThread extends Thread{  
  private int threadnum; 
    
  public TestThread(int threadnum) {  
    this.threadnum = threadnum;  
  } 
    
  public static synchronized void staticTest(int threadnum) {  
    for(int i = 0;i<1000;i++){  
      System.out.println("NO." + threadnum + ":" + i ); 
    }  
  }  
  
  public static void main(String[] args) throws Exception {  
    for(int i=0; i<10; i++){ 
      new TestThread(i).start(); 
      Thread.sleep(1); 
    } 
  }  
    
  @Override
  public void run(){ 
    staticTest(threadnum); 
  } 
}
Copier après la connexion

Le résultat d'exécution est le même que dans le deuxième exemple.


Le contenu ci-dessus explique principalement deux problèmes : le bloc de synchronisation et la méthode de synchronisation.
1. Bloc de synchronisation : Le verrou d'objet acquis est le verrou d'objet drapeau en synchronisé (drapeau).
2. Méthode synchrone : ce qui est obtenu est l'objet de classe auquel appartient la méthode et le verrou de l'objet de classe.
Méthode de synchronisation statique, puisque plusieurs threads la partageront, elle sera définitivement synchronisée.
Au lieu d'une méthode de synchronisation statique, elle ne sera synchronisée qu'en mode singleton.


Pour plus d'explications sur l'utilisation de base du mot-clé synchronisé dans la programmation multi-thread Java, veuillez faire attention au site Web PHP chinois !


Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Commandes de chat et comment les utiliser
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment fonctionne le mécanisme de chargement de classe de Java, y compris différents chargeurs de classe et leurs modèles de délégation? Comment fonctionne le mécanisme de chargement de classe de Java, y compris différents chargeurs de classe et leurs modèles de délégation? Mar 17, 2025 pm 05:35 PM

Le chargement de classe de Java implique le chargement, la liaison et l'initialisation des classes à l'aide d'un système hiérarchique avec Bootstrap, Extension et Application Classloaders. Le modèle de délégation parent garantit que les classes de base sont chargées en premier, affectant la classe de classe personnalisée LOA

Comment implémenter la mise en cache à plusieurs niveaux dans les applications Java à l'aide de bibliothèques comme la caféine ou le cache de goyave? Comment implémenter la mise en cache à plusieurs niveaux dans les applications Java à l'aide de bibliothèques comme la caféine ou le cache de goyave? Mar 17, 2025 pm 05:44 PM

L'article examine la mise en œuvre de la mise en cache à plusieurs niveaux en Java à l'aide de la caféine et du cache de goyave pour améliorer les performances de l'application. Il couvre les avantages de configuration, d'intégration et de performance, ainsi que la gestion de la politique de configuration et d'expulsion le meilleur PRA

Comment puis-je utiliser JPA (Java Persistance API) pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux? Comment puis-je utiliser JPA (Java Persistance API) pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux? Mar 17, 2025 pm 05:43 PM

L'article discute de l'utilisation de JPA pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux. Il couvre la configuration, la cartographie des entités et les meilleures pratiques pour optimiser les performances tout en mettant en évidence les pièges potentiels. [159 caractères]

Comment utiliser Maven ou Gradle pour la gestion avancée de projet Java, la création d'automatisation et la résolution de dépendance? Comment utiliser Maven ou Gradle pour la gestion avancée de projet Java, la création d'automatisation et la résolution de dépendance? Mar 17, 2025 pm 05:46 PM

L'article discute de l'utilisation de Maven et Gradle pour la gestion de projet Java, la construction de l'automatisation et la résolution de dépendance, en comparant leurs approches et leurs stratégies d'optimisation.

Mar 17, 2025 pm 05:45 PM

L'article discute de la création et de l'utilisation de bibliothèques Java personnalisées (fichiers JAR) avec un versioning approprié et une gestion des dépendances, à l'aide d'outils comme Maven et Gradle.

See all articles