Travailler avec les files d'attente de tâches en Kotlin : en pratique

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 Kotlin ?

\n

Les applications modernes nécessitent de plus en plus souvent un traitement parallèle des données, des opérations en arrière-plan et des appels asynchrones. Sans une gestion judicieuse des tâches, votre code peut rencontrer des problèmes de performance, des fuites mémoire ou des « blocages » de l'interface. Les files d'attente de tâches en Kotlin ne sont pas simplement une abstraction, mais un outil puissant qui aide à organiser l'exécution du travail dans l'ordre souhaité, avec un contrôle du nombre de threads et des priorités.

\n

Dans cet article, nous allons examiner les approches pratiques pour implémenter des files d'attente de tâches en Kotlin : du classique ThreadPoolExecutor aux coroutines avec leurs dispatchteurs flexibles. Vous verrez comment appliquer ces techniques dans des projets réels et obtiendrez des exemples de code prêts à l'emploi.

\n\n

1. Approche classique : ThreadPoolExecutor et BlockingQueue

\n

La bibliothèque standard de Java (et Kotlin, en tant que langage JVM) fournit une classe puissante ThreadPoolExecutor. Elle gère un pool de threads et utilise une file d'attente bloquante interne pour stocker les tâches en attente.

\n\n

Création d'une file d'attente avec un nombre fixe de threads

\n

Le cas le plus simple est un pool avec un nombre fixe de threads. Toutes les tâches qui ne peuvent pas être exécutées immédiatement sont placées dans une file d'attente LinkedBlockingQueue.

\n\n
import java.util.concurrent.Executors\nimport java.util.concurrent.TimeUnit\n\nfun main() {\n    val executor = Executors.newFixedThreadPool(3)\n\n    for (i in 1..10) {\n        executor.submit {\n            println("Tâche $i exécutée dans le thread ${Thread.currentThread().name}")\n            Thread.sleep(1000)\n        }\n    }\n\n    executor.shutdown()\n    executor.awaitTermination(1, TimeUnit.MINUTES)\n    println("Toutes les tâches sont terminées")\n}\n
\n

Ce code illustre une file d'attente de base : les tâches sont soumises au pool, et si tous les threads sont occupés, elles attendent dans la file.

\n\n

File d'attente prioritaire : PriorityBlockingQueue

\n

Parfois, il est nécessaire d'exécuter les tâches urgentes avant les autres. Pour cela, nous utilisons PriorityBlockingQueue avec un comparateur personnalisé.

\n\n
import java.util.concurrent.PriorityBlockingQueue\nimport java.util.concurrent.ThreadPoolExecutor\nimport java.util.concurrent.TimeUnit\n\ndata class PriorityTask(val priority: Int, val name: String) : Comparable<PriorityTask> {\n    override fun compareTo(other: PriorityTask): Int = other.priority - this.priority\n}\n\nfun main() {\n    val queue = PriorityBlockingQueue<Runnable>(10) { r1, r2 ->\n        val t1 = (r1 as PriorityTaskWrapper).task\n        val t2 = (r2 as PriorityTaskWrapper).task\n        t1.compareTo(t2)\n    }\n\n    val executor = ThreadPoolExecutor(2, 4, 1, TimeUnit.SECONDS, queue)\n\n    class PriorityTaskWrapper(val task: PriorityTask, val action: () -> Unit) : Runnable {\n        override fun run() = action()\n    }\n\n    for (i in 1..5) {\n        val priority = if (i % 2 == 0) 10 else 1\n        executor.submit(PriorityTaskWrapper(PriorityTask(priority, "Tâche $i")) {\n            println("Exécution : ${PriorityTask(priority, "Tâche $i")}")\n            Thread.sleep(500)\n        })\n    }\n\n    executor.shutdown()\n    executor.awaitTermination(1, TimeUnit.MINUTES)\n}\n
\n

Ici, les tâches avec priority = 10 seront exécutées avant celles avec priority = 1, même si elles sont ajoutées plus tard.

\n\n

2. Files d'attente de tâches avec les coroutines (kotlinx.coroutines)

\n

Le Kotlin moderne propose les coroutines — des threads légers qui permettent de construire des files d'attente asynchrones sans gestion directe des threads. L'outil principal est Channel et les Dispatchers.

\n\n

File d'attente simple via Channel

\n

Channel est l'équivalent d'une file d'attente bloquante, mais pour les coroutines. Il permet de transférer en toute sécurité des tâches entre les coroutines.

\n\n
import kotlinx.coroutines.*\nimport kotlinx.coroutines.channels.Channel\n\nsuspend fun processTas                

Blogs

Book Recommendations