In Java, inter-thread communication is a mechanism that allows threads to coordinate their activities and communicate with each other. It enables one thread to notify another thread when a certain condition is met or a certain task is completed. Inter-thread communication is achieved through the use of shared objects, locks, and synchronization mechanisms.
The two main ways to achieve inter-thread communication in Java are:
1. Wait-notify mechanism
2. Blocking Queue
1. Wait-notify mechanism:
This mechanism involves two methods, wait() and notify(), which are used to block and wake up threads. The wait() method is called by a thread that wants to wait for a specific condition to be met. The notify() method is called by a thread that has completed a task and wants to notify other threads waiting on the same object that the condition has been met. The notifyAll() method can also be used to wake up all threads waiting on the same object.
Here's an example that demonstrates how to use the wait-notify mechanism in Java:
public class WaitNotifyExample {
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
Thread producer = new Thread(() -> {
synchronized (lock) {
System.out.println("Producer is producing...");
try {
Thread.sleep(1000);
lock.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread consumer = new Thread(() -> {
synchronized (lock) {
System.out.println("Consumer is waiting...");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Consumer has consumed...");
}
});
producer.start();
consumer.start();
}
}
In this example, we create two threads, a producer and a consumer. The producer thread acquires the lock on the lock object and produces a message after a delay of 1 second. It then calls the notify() method on the lock object to wake up the waiting threads.
The consumer thread acquires the lock on the lock object and waits for a notification by calling the wait() method. When the producer thread calls notify(), the consumer thread is notified and continues executing, printing "Consumer has consumed...".
2. Blocking Queue:A blocking queue is a data structure that allows threads to insert and remove elements from the queue. If the queue is empty, threads attempting to remove elements will be blocked until an element is added, and if the queue is full, threads attempting to add elements will be blocked until space becomes available.
Here's an example that demonstrates how to use a blocking queue in Java:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BlockingQueueExample {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
Thread producer = new Thread(() -> {
try {
for (int i = 1; i <= 10; i++) {
queue.put(i);
System.out.println("Producer is producing " + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread consumer = new Thread(() -> {
try {
for (int i = 1; i <= 10; i++) {
Integer value = queue.take();
System.out.println("Consumer has consumed " + value);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
producer.start();
consumer.start();
}
}
In this example, we create a blocking queue with a capacity of 10. the producer thread produces values and inserts them into the queue using put(). The consumer thread waits for values to become available in the queue using take() and then consumes them.
Note: Both of these examples demonstrate the producer-consumer pattern, which is a common use case for inter-thread communication.