Maison  >  Article  >  Java  >  Comment utiliser la classe CountDownLatch de Java Concurrency Toolkit ?

Comment utiliser la classe CountDownLatch de Java Concurrency Toolkit ?

PHPz
PHPzavant
2023-05-09 18:22:281192parcourir

CountDownLatch est une classe d'outils très pratique du package de concurrence Java, qui peut nous aider à réaliser la synchronisation et la collaboration entre les threads. L'idée principale de CountDownLatch est de contrôler l'ordre d'exécution des threads via un compteur. Lorsque la valeur du compteur tombe à 0, tous les threads en attente seront réveillés et commenceront alors à effectuer l'opération suivante.

1. Interprétation du code source de CountDownLatch

En Java, l'implémentation de CountDownLatch est basée sur la classe AbstractQueuedSynchronizer. AbstractQueuedSynchronizer est un synchroniseur très important. De nombreuses classes de concurrence en Java sont implémentées sur cette base, telles que Semaphore, ReentrantLock, ReadWriteLock, etc.

La classe d'implémentation principale de CountDownLatch est Sync, qui est une classe interne héritée de AbstractQueuedSynchronizer. Voici le code source de la classe Sync :

private static final class Sync extends AbstractQueuedSynchronizer {
    Sync(int count) {
        setState(count);
    }

    int getCount() {
        return getState();
    }

    protected int tryAcquireShared(int acquires) {
        return (getState() == 0) ? 1 : -1;
    }

    protected boolean tryReleaseShared(int releases) {
        for (;;) {
            int c = getState();
            if (c == 0)
                return false;
            int nextc = c-1;
            if (compareAndSetState(c, nextc))
                return nextc == 0;
        }
    }
}

Il existe trois méthodes importantes dans la classe Sync :

  • tryAcquireShared(int acquiert ) : Essayez d'acquérir le verrou, si la valeur du compteur est égale à 0, cela signifie que tous les threads ont terminé leur exécution, et 1 est renvoyé sinon, -1 est renvoyé, indiquant que l'acquisition du verrou a échoué.

  • tryReleaseShared(int releases) : relâchez le verrou, décrémentez la valeur du compteur de 1 et renvoyez la valeur du compteur après avoir décrémenté 1. Si la valeur du compteur diminue jusqu'à 0, cela signifie que tous les threads ont terminé leur exécution et renvoie vrai, sinon il renvoie faux.

  • getCount() : Renvoie la valeur du compteur actuel. La méthode

tryAcquireShared() est la clé de CountDownLatch, elle tentera d'acquérir le verrou. Si la valeur du compteur est égale à 0, cela signifie que tous les threads ont terminé leur exécution, et 1 peut être renvoyé, indiquant que l'acquisition du verrou a réussi ; sinon, -1 est renvoyé, indiquant que l'acquisition du verrou a échoué ; La méthode de base de la classe AbstractQueuedSynchronizer est utilisée ici, à savoir la méthode getState(), qui permet d'obtenir l'état du synchroniseur. La méthode

tryReleaseShared() est utilisée pour libérer le verrou, décrémenter la valeur du compteur de 1 et renvoyer la valeur du compteur après avoir décrémenté 1. Si la valeur du compteur diminue à 0, cela signifie que tous les threads ont terminé leur exécution et renvoie vrai, sinon il renvoie faux. La méthode de base de la classe AtomicInteger est utilisée ici, à savoir la méthode compareAndSetState(), qui permet de comparer et de définir l'état du synchroniseur.

2. Analyse du principe de CountDownLatch

Le principe de fonctionnement de CountDownLatch est très simple Il utilise un compteur pour contrôler l'ordre d'exécution des threads. Lorsque la valeur du compteur tombe à 0, tous les threads en attente seront réveillés et commenceront alors à effectuer l'opération suivante.

CountDownLatch est une classe d'outils de collaboration multithread qui permet à un ou plusieurs threads d'attendre que d'autres threads terminent une opération avant de continuer à s'exécuter. CountDownLatch a un compteur Lorsque la valeur du compteur devient 0, le thread en attente sera réveillé. L'utilisation de CountDownLatch est très simple, comprenant principalement deux méthodes : wait() et countDown(). Méthode

  • await() : Cette méthode bloque le thread actuel jusqu'à ce que la valeur du compteur devienne 0. Méthode

  • countDown() : Cette méthode décrémentera la valeur du compteur de 1.

Ce qui suit est un exemple de code simple :

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        final int count = 3;
        final CountDownLatch latch = new CountDownLatch(count);

        for (int i = 0; i < count; i++) {
            new Thread(() -> {
                // 线程执行任务
                System.out.println(Thread.currentThread().getName() + " 执行任务...");
                // 任务执行完毕,计数器减1
                latch.countDown();
            }).start();
        }

        // 等待所有任务执行完毕
        latch.await();
        System.out.println("所有任务执行完毕...");
    }
}

Dans cet exemple de code, nous créons un objet CountDownLatch et initialisons le compteur à 3. Ensuite, 3 threads sont créés, chaque thread effectue une tâche. Une fois la tâche terminée, le compteur est décrémenté de 1. Enfin, appelez la méthode latch.await() dans le thread principal pour attendre que toutes les tâches soient terminées.

Le principe d'implémentation de CountDownLatch est basé sur la classe AbstractQueuedSynchronizer. Lorsque nous appelons la méthode wait(), le thread tentera d'acquérir le verrou. Si la valeur du compteur n'est pas 0, l'acquisition du verrou échouera et le thread sera ajouté à la file d'attente de synchronisation et bloqué. Lorsque nous appelons la méthode countDown(), la valeur du compteur sera réduite de 1. Si la valeur du compteur est réduite à 0, cela signifie que tous les threads ont terminé leur exécution. À ce moment, les threads de la file d'attente de synchronisation seront réveillés et. continuez à effectuer l’opération suivante.

Plus précisément, dans la classe Sync, la méthode tryAcquireShared(int acquires) tentera d'acquérir le verrou. Si la valeur du compteur est égale à 0, cela signifie que tous les threads ont terminé leur exécution et renvoient. 1, sinon il renvoie -1 , indiquant l'échec de l'acquisition du verrou. La méthode tryReleaseShared(int releases) est utilisée pour libérer le verrou, décrémenter la valeur du compteur de 1 et renvoyer la valeur du compteur après avoir décrémenté 1. Si la valeur du compteur diminue jusqu'à 0, cela signifie que tous les threads ont terminé leur exécution et renvoie vrai, sinon il renvoie faux.

3. Scénarios d'application de CountDownLatch

CountDownLatch est une classe d'outils très pratique qui peut nous aider à réaliser la synchronisation et la collaboration entre les threads. Voici quelques scénarios d'application courants pour CountDownLatch :

  • Attente de la fin de plusieurs threads : si plusieurs threads doivent être exécutés, vous devez attendre que tous les threads soient exécutés. terminer avant de continuer. L’étape suivante peut être réalisée en utilisant CountDownLatch. Nous pouvons créer un objet CountDownLatch et initialiser la valeur du compteur au nombre de threads. Une fois l'exécution de chaque thread terminée, appelez la méthode countDown() pour décrémenter le compteur de 1. Enfin, appelez la méthode wait() dans le thread principal pour attendre que tous les threads terminent leur exécution.

  • Contrôlez l'ordre d'exécution des threads : si plusieurs threads doivent être exécutés dans un ordre spécifique, vous pouvez utiliser CountDownLatch pour y parvenir. Nous pouvons créer plusieurs objets CountDownLatch et la valeur du compteur de chaque objet est 1, indiquant qu'un seul thread peut s'exécuter. Une fois l’exécution du thread terminée, appelez la méthode countDown() du prochain objet CountDownLatch pour réveiller le thread suivant.

  • Attente qu'un événement externe se produise : Si nous devons attendre qu'un événement externe se produise, comme l'établissement d'une connexion réseau ou la fin de la lecture d'un fichier, nous pouvons utiliser CountDownLatch pour implémenter. Nous pouvons créer un objet CountDownLatch dans le thread principal, initialiser la valeur du compteur à 1, puis attendre que l'événement externe se produise dans un autre thread. Lorsqu'un événement externe se produit, appelez la méthode countDown() de l'objet CountDownLatch pour réveiller le thread principal afin de poursuivre l'exécution.

  • Contrôler le nombre de threads simultanés : Si nous devons contrôler le nombre de threads simultanés, nous pouvons utiliser CountDownLatch pour y parvenir. Nous pouvons créer un objet CountDownLatch et initialiser la valeur du compteur au nombre de threads. Une fois l'exécution de chaque thread terminée, appelez la méthode countDown() pour décrémenter le compteur de 1. Si un thread doit attendre que d'autres threads terminent son exécution, il peut appeler la méthode wait() pour attendre que la valeur du compteur devienne 0.

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer