Introduction : pourquoi les files d'attente de tâches en Java ?
\n\nChaque développeur rencontre tôt ou tard la nécessité d'organiser le traitement de flux de données. Imaginez un serveur web qui reçoit des milliers de requêtes par seconde, ou un système traitant les commandes d'une boutique en ligne. Il est impossible de tout traiter immédiatement — les ressources sont limitées. C'est là que les files d'attente de tâches (task queues) viennent à la rescousse.
\n\nEn Java, une file d'attente de tâches n'est pas simplement une structure de données FIFO (First In, First Out). C'est un outil puissant pour :
\n- \n
- Séparer la production et la consommation de tâches (modèle Producer-Consumer) \n
- Gérer la charge — les tâches s'accumulent dans la file lorsque le système est occupé \n
- Le traitement asynchrone — le thread producteur n'attend pas que la tâche soit exécutée \n
- L'équilibrage entre les threads — plusieurs workers récupèrent les tâches d'une file commune \n
Dans cet article, nous allons aborder tous les aspects essentiels du travail avec les files d'attente en Java : des interfaces de base du Collection Framework aux files d'attente thread-safe pour les applications multithread.
\n\nFiles d'attente de base : Queue et Deque
\n\nInterface Queue
\n\nL'interface java.util.Queue est la base de toutes les files d'attente en Java. Elle fournit les opérations standard pour travailler avec une file :
| Opération | Exception en cas d'erreur | Retour d'une valeur spéciale |
|---|---|---|
| Ajout | add(e) | offer(e) |
| Extraction et suppression | remove() | poll() |
| Consultation (sans suppression) | element() | peek() |
La différence entre les méthodes est évidente : si la file est vide, remove() et element() lèveront une NoSuchElementException, tandis que poll() et peek() retourneront null.
Les implémentations les plus populaires de Queue :
\n- \n
- LinkedList — liste doublement chaînée, fonctionne comme une file FIFO classique \n
- PriorityQueue — file d'attente avec priorité, les éléments sont extraits dans l'ordre défini par un Comparator \n
- ArrayDeque — file d'attente double basée sur un tableau \n
Exemple : file d'attente de tâches simple avec LinkedList
\n\nimport java.util.LinkedList;\nimport java.util.Queue;\n\npublic class SimpleTaskQueue {\n public static void main(String[] args) {\n Queue<String> taskQueue = new LinkedList<>();\n\n // Ajout de tâches\n taskQueue.offer("Charger les données depuis la BD");\n taskQueue.offer("Envoyer une notification par email");\n taskQueue.offer("Générer le rapport");\n\n System.out.println("File d'attente : " + taskQueue);\n\n // Traitement de toutes les tâches\n while (!taskQueue.isEmpty()) {\n String task = taskQueue.poll();\n System.out.println("Exécution : " + task);\n }\n\n System.out.println("Toutes les tâches sont terminées !");\n }\n}\n\nInterface Deque
\n\nDeque (Double Ended Queue) permet d'ajouter et d'extraire des éléments des deux extrémités. Cela offre de la flexibilité : la file peut fonctionner comme une pile (LIFO) ou comme une file classique (FIFO).
Méthodes principales de Deque :
\n- \n
addFirst()/offerFirst()— ajouter au début \n addLast()/offerLast()— ajouter à la fin \n removeFirst()/pollFirst()— extraire du début \n removeLast()/pollLast()— extraire de la fin \n
Exemple : Deque comme pile pour les tâches différées
\n\nimport java.util.ArrayDeque;\nimport java.util.Deque;\n\npublic class DequeExample {\n public static void main(String[] args) {\n De