Middle
Comment organiser l'échange de données entre deux threads en Java?
sobes.tech IA
Réponse de l'IA
L'échange de données entre threads en Java peut être organisé de plusieurs manières:
- Variables partagées avec synchronisation: Les threads utilisent des variables partagées, auxquelles l'accès est synchronisé à l'aide du mot-clé
synchronized, de verrous (Lockdejava.util.concurrent.locks) ou de variables atomiques (Atomicdejava.util.concurrent.atomic). - Tuyaux de données (Streams liés): Les flux d'entrée/sortie liés (
PipedInputStreametPipedOutputStream) permettent à un thread d'écrire des données et à un autre de les lire.// Utilisation des Streams liés try { PipedOutputStream pout = new PipedOutputStream(); PipedInputStream pin = new PipedInputStream(pout); // Thread 1: écriture new Thread(() -> { try { pout.write("Bonjour du thread 1".getBytes()); pout.close(); } catch (Exception e) { e.printStackTrace(); } }).start(); // Thread 2: lecture new Thread(() -> { try { int data; while ((data = pin.read()) != -1) { System.out.print((char) data); } pin.close(); } catch (Exception e) { e.printStackTrace(); } }).start(); } catch (Exception e) { e.printStackTrace(); } - Queues: L'utilisation de collections thread-safe, telles que
BlockingQueue(par exemple,ArrayBlockingQueue,LinkedBlockingQueue), permet à un thread d'ajouter des éléments à la file d'attente et à un autre de les retirer.import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; // Utilisation de BlockingQueue BlockingQueue<String> queue = new LinkedBlockingQueue<>(); // Producteur new Thread(() -> { try { queue.put("Message 1"); queue.put("Message 2"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); // Consommateur new Thread(() -> { try { System.out.println(queue.take()); System.out.println(queue.take()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); - Mécanismes
wait(),notify(),notifyAll(): Utilisés pour synchroniser les threads basés sur des moniteurs d'objets. Un thread appellewait()pour attendre une condition, un autre appellenotify()ounotifyAll()pour notifier les threads en attente d'un changement de condition.// Utilisation de wait/notify class Data { private String message; private boolean empty = true; public synchronized String read() { while (empty) { try { wait(); // Attente de données } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = true; notifyAll(); // Notification de la disponibilité pour écrire return message; } public synchronized void write(String message) { while (!empty) { try { wait(); // Attente que les données précédentes soient lues } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = false; this.message = message; notifyAll(); // Notification de nouvelles données } } CompletableFuture: Permet de créer des calculs asynchrones et de les combiner, facilitant l'échange de données via des valeurs de retour et des gestionnaires de fin.Exchanger: Permet à deux threads d'échanger des objets à un point de synchronisation.
Le choix d'une méthode spécifique dépend de la nature de la tâche, du niveau de synchronisation requis, des performances et de la complexité de l'implémentation.