Maison  >  Article  >  Java  >  Comment les méthodes Java `wait()` et `notify()` implémentent-elles une file d'attente de blocage ?

Comment les méthodes Java `wait()` et `notify()` implémentent-elles une file d'attente de blocage ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-23 05:56:16682parcourir

How Do Java's `wait()` and `notify()` Methods Implement a Blocking Queue?

wait() et notify() en Java : un scénario simple avec file d'attente

En Java, wait() et notify() Les méthodes fournissent un mécanisme de synchronisation des threads. Explorons un scénario simple dans lequel ces méthodes peuvent être utilisées pour implémenter une file d'attente de blocage.

Implémentation de la file d'attente de blocage

Une file d'attente de blocage est une structure de données de file d'attente qui bloque les threads lorsque essayer d'effectuer certaines opérations si des conditions spécifiques ne sont pas remplies. Dans notre implémentation, nous implémenterons les méthodes put() et take(), qui bloqueront respectivement si la file d'attente est pleine ou vide.

public class BlockingQueue<T> {

    private Queue<T> queue = new LinkedList<>();
    private int capacity;

    public BlockingQueue(int capacity) {
        this.capacity = capacity;
    }

    // Blocks if the queue is full (no space to insert)
    public synchronized void put(T element) throws InterruptedException {
        while (queue.size() == capacity) {
            wait();
        }

        queue.add(element);
        notifyAll();
    }

    // Blocks if the queue is empty (nothing to remove)
    public synchronized T take() throws InterruptedException {
        while (queue.isEmpty()) {
            wait();
        }

        T item = queue.remove();
        notifyAll();
        return item;
    }
}

Utilisation

Voyons maintenant comment utiliser cette file d'attente de blocage.

BlockingQueue<Integer> queue = new BlockingQueue<>(10);

// Producer thread: adds elements to the queue
new Thread(() -> {
    for (int i = 0; i < 15; i++) {
        try {
            queue.put(i);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}).start();

// Consumer thread: retrieves elements from the queue
new Thread(() -> {
    for (int i = 0; i < 15; i++) {
        try {
            System.out.println(queue.take());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}).start();

Dans cet exemple, le thread producteur ajoutera des éléments à la file d'attente, bloquant lorsqu'il atteindra le limite de capacité. Le thread consommateur récupérera les éléments et les bloquera lorsque la file d'attente est vide.

Considérations clés

  • Utilisez des blocs synchronisés : wait() et notify() doivent être utilisés dans les blocs synchronisés pour garantir la sécurité des threads et éviter les signaux manqués.
  • Utilisez un while loop: Utilisez une boucle while pour vérifier les conditions dues à des réveils parasites (lorsqu'un thread est réactivé sans en être averti).
  • Considérez la bibliothèque de concurrence Java 1.5 : Java 1.5 a introduit une bibliothèque de concurrence avec des abstractions de niveau supérieur (par exemple, Lock and Condition). Il offre une approche plus propre et plus polyvalente.

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:
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