Files d'attente de tâches en Java : guide pratique avec exemples

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : pourquoi les files d'attente de tâches en Java ?

\n\n

Dans le développement moderne en Java, le multithreading n'est pas un luxe, mais une nécessité. Les applications traitent des milliers de requêtes, exécutent des tâches en arrière-plan et interagissent avec des services externes. Sans une organisation correcte des files d'attente de tâches, le code devient chaotique : les threads se bloquent mutuellement, la mémoire est saturée et les performances chutent.

\n\n

Les files d'attente de tâches (Task Queues) sont un mécanisme qui permet de répartir efficacement le travail entre les threads. En Java, il existe un ensemble d'outils puissants dans le package java.util.concurrent. Dans cet article, nous allons voir comment utiliser les files d'attente de tâches en pratique, avec des exemples de code réels.

\n\n

Vous apprendrez :

\n
    \n
  • Comment fonctionnent BlockingQueue et ses implémentations
  • \n
  • Comment configurer ThreadPoolExecutor pour des tâches spécifiques
  • \n
  • Comment éviter les erreurs typiques lors du travail avec les files d'attente
  • \n
  • Comment tester et déboguer du code multithread
  • \n
\n\n

Bases des files d'attente de tâches : BlockingQueue

\n\n

BlockingQueue est une interface qui est à la base de la plupart des files d'attente de tâches en Java. Elle prend en charge les opérations d'attente : si la file est vide, le thread consommateur attend qu'un élément apparaisse ; si la file est pleine, le thread producteur attend qu'une place se libère.

\n\n

Implémentations principales de BlockingQueue

\n\n

En Java, il existe plusieurs implémentations de BlockingQueue, chacune avec ses spécificités :

\n\n
    \n
  • ArrayBlockingQueue — taille fixe, basée sur un tableau. Adaptée aux scénarios avec une limite de tâches connue.
  • \n
  • LinkedBlockingQueue — optionnellement limitée, basée sur une liste chaînée. Idéale pour les charges dynamiques.
  • \n
  • PriorityBlockingQueue — file illimitée avec priorités. Utilisée lorsque les tâches ont une importance différente.
  • \n
  • SynchronousQueue — file sans capacité : chaque insert doit attendre le remove correspondant. Parfaite pour le transfert direct de tâches.
  • \n
\n\n

Exemple : file d'attente de tâches simple avec ArrayBlockingQueue

\n\n

Considérons un exemple de base où un thread génère des tâches et un autre les traite :

\n\n
import java.util.concurrent.ArrayBlockingQueue;\nimport java.util.concurrent.BlockingQueue;\n\npublic class SimpleTaskQueue {\n    public static void main(String[] args) {\n        BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);\n\n        // Thread producteur\n        Thread producer = new Thread(() -> {\n            try {\n                for (int i = 1; i <= 20; i++) {\n                    String task = "Tâche n°" + i;\n                    queue.put(task); // Bloque si la file est pleine\n                    System.out.println("Ajoutée : " + task);\n                    Thread.sleep(100); // Simulation de génération\n                }\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n        });\n\n        // Thread consommateur\n        Thread consumer = new Thread(() -> {\n            try {\n                while (true) {\n                    String task = queue.take(); // Bloque si la file est vide\n                    System.out.println("Traitée : " + task);\n                    Thread.sleep(300); // Simulation de traitement\n                }\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n        });\n\n        producer.start();\n        consumer.start();\n    }\n}\n
\n\n

Ce code illustre le modèle clé : le producteur ajoute des tâches via put(), le consommateur les récupère via take(). Les deux méthodes se bloquent si nécessaire, assurant une synchronisation naturelle.

\n\n

ThreadPoolExecutor : file d'attente de tâches professionnelle

\n\n

En pratique, on utilise rarement

Blogs

Book Recommendations