Middle
How can data exchange be organized between two threads in Java?
sobes.tech AI
Answer from AI
Data exchange between threads in Java can be organized using the following methods:
- Shared variables with synchronization: Threads use shared variables, access to which is synchronized using the
synchronizedkeyword, locks (Lockfromjava.util.concurrent.locks), or atomic variables (Atomicfromjava.util.concurrent.atomic). - Data pipelines (Piped Streams): Connected input/output streams (
PipedInputStreamandPipedOutputStream) allow one thread to write data and another to read it.// Using Piped Streams try { PipedOutputStream pout = new PipedOutputStream(); PipedInputStream pin = new PipedInputStream(pout); // Thread 1: writing new Thread(() -> { try { pout.write("Hello from thread 1".getBytes()); pout.close(); } catch (Exception e) { e.printStackTrace(); } }).start(); // Thread 2: reading 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: Using thread-safe collections such as
BlockingQueue(e.g.,ArrayBlockingQueue,LinkedBlockingQueue) allows one thread to put elements into the queue and another to retrieve them.import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; // Using BlockingQueue BlockingQueue<String> queue = new LinkedBlockingQueue<>(); // Producer new Thread(() -> { try { queue.put("Message 1"); queue.put("Message 2"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); // Consumer new Thread(() -> { try { System.out.println(queue.take()); System.out.println(queue.take()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); wait(),notify(),notifyAll(): Used for thread synchronization based on object monitors. One thread callswait()to wait for a condition, another callsnotify()ornotifyAll()to notify waiting threads about a change in the condition.// Using wait/notify class Data { private String message; private boolean empty = true; public synchronized String read() { while (empty) { try { wait(); // Waiting for data } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = true; notifyAll(); // Notify about possible writing return message; } public synchronized void write(String message) { while (!empty) { try { wait(); // Waiting for previous data to be read } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = false; this.message = message; notifyAll(); // Notify about new data } }CompletableFuture: Allows creating asynchronous computations and combining their results, enabling data exchange through return values and completion handlers.Exchanger: Allows two threads to exchange objects at a synchronization point.
The choice of a specific method depends on the task's specifics, required synchronization level, performance, and implementation complexity.