Inter-thread Communication in Java
Introduction to Inter-thread Communication in Java
Inter-thread communication is crucial in Multithreading, a core concept in Java. Multithreading allows simultaneous execution of two or more parts of a program to maximize CPU utilization. In this tutorial, we will delve into the concept of inter-thread communication in Java, various ways to achieve it, and its importance.
What is Inter-thread Communication?
Inter-thread communication involves two or more threads working together to achieve a common goal. In Java, threads can communicate with each other by using methods like wait()
, notify()
, and notifyAll()
.
wait(), notify() and notifyAll() Methods
Java provides the wait()
, notify()
, and notifyAll()
methods as part of the Object class. They are used to communicate between threads in Java. Here's a brief about these methods:
- wait(): This method tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify().
- notify(): It wakes up one single thread that called wait() on the same object. It should be noted that calling notify() does not actually give up a lock on a resource.
- notifyAll(): It wakes up all the threads that called wait() on the same object.
Synchronized Block and Inter-thread Communication
Inter-thread communication cannot exist in isolation. It needs to be coupled with the concept of synchronized blocks. Only a thread that owns a lock on an object can call wait()
, notify()
, and notifyAll()
on it.
A synchronized block in Java is marked with the synchronized
keyword. A synchronized block in Java is used to lock an object for any shared resource. When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the thread completes its task.
Code Example
Here is a simple example of Inter-thread communication in Java:
class Chat {
boolean flag = false;
public synchronized void Question(String msg) {
if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(msg);
flag = true;
notify();
}
public synchronized void Answer(String msg) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(msg);
flag = false;
notify();
}
}
class T1 implements Runnable {
Chat m;
String[] s1 = { "Hi", "How are you ?", "I am also doing fine!" };
public T1(Chat m1) {
this.m = m1;
new Thread(this, "Question").start();
}
public void run() {
for (int i = 0; i < s1.length; i++) {
m.Question(s1[i]);
}
}
}
class T2 implements Runnable {
Chat m;
String[] s2 = { "Hi", "I am good, what about you?", "Great!" };
public T2(Chat m2) {
this.m = m2;
new Thread(this, "Answer").start();
}
public void run() {
for (int i = 0; i < s2.length; i++) {
m.Answer(s2[i]);
}
}
}
public class TestThread {
public static void main(String[] args) {
Chat m = new Chat();
new T1(m);
new T2(m);
}
}
In the above example, two threads T1
and T2
are communicating with each other using the wait()
and notify()
methods.
Conclusion
In this article, we have covered inter-thread communication in Java, which is a key concept in multithreading. We learned about the wait()
, notify()
and notifyAll()
methods and how to use them for inter-thread communication. We also saw how synchronization is necessary for these methods to work correctly. Finally, we implemented a simple chat program to showcase inter-thread communication.
Understanding these concepts is vital as they form the foundation for advanced topics in Java like thread pooling, deadlock, and starvation. Happy learning!