What is inter Thread communication?

  • Inter Thread Communication is When two threads are communicating with each other
  • Inter thread communication can be achieved by using wait() and notify() or notifyAll() method.
  • Thread expecting an update is responsible to call the wait() method immediately thread will enter into the waiting state.
  • Thread is responsible for performing an update, after completing the update it is responsible for calling notify() method.
  • Once notify method is called, the waiting thread will get that notification and continue its execution with those updated items.
  • The thread should be the owner of the object on which the wait method is called. That is that object should be locked by the thread object hence this method is called only in synchronized block else we will get IllegalMonitorStateException.
  • If the thread calls a wait() method it immediately releases the lock on that particular object and enters into a waiting state.
  • If a thread calls a notify() method may not release the lock of the object immediately.
  • Except for wait(), notify(), and notifyAll() there is no method where the thread releases a lock.
  • Note that every wait method throws InterruptedException.
  • We can use notify method to give notification for only one waiting thread, if multiple threads are waiting then only one thread will be notified and the remaining threads have to wait for further notifications.
  • Which thread will be notified depends on the JVM.
  • To notify all the threads at once we can use the notifyAll method.

Let’s see the example below for Inter Thread Communication:

Java Code
class Test {
public static void main(String args[]) throws InterruptedException {
Greet g = new Greet();

PrintThread t1 = new PrintThread(g);
UpdateThread t2 = new UpdateThread(g);

t1.start();
t2.start();
}
}

class UpdateThread extends Thread {
Greet greet;

public UpdateThread(Greet greet) {
this.greet = greet;
}

public void run() {
greet.update();
}
}

class PrintThread extends Thread {
Greet greet;

public PrintThread(Greet greet) {
this.greet = greet;
}

public void run() {
greet.print();
}
}

class Greet {
private boolean updating = true;

public synchronized void update() {
System.out.println(“Inside Update start”);
while (updating) {
try {
wait(5000);
for (int i = 0; i < 5; i++) {
System.out.println(“Updating…”);
}
updating = false;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println(“Thread Interrupted”);
}
}
System.out.println(“Inside Update end”);
notify(); // — Line 1
}

public synchronized void print() {
System.out.println(“Inside print start”);
while (updating) {
try {
wait(); // — Line 2
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println(“Thread Interrupted”);
}
}
System.out.println(“Inside print end”);
updating = false;
}
}
Output:
Inside print start
Inside Update start
Updating…
Updating…
Updating…
Updating…
Updating…
Inside Update end
Inside print end
  • In the above example until the update thread operation is not completed print thread will wait for notification from the update thread, once notify method is called the print thread will continue its execution.
  • If we comment on Line 1, then the print thread will not be notified and will remain in the waiting state forever until notify() is called.
  • If we comment the Line 1 and Line 2 and add wait(5000) then we will get the output, print thread will wait for some time and will continue its execution once the lock is released by the update thread, it will not wait for notification.

What is DeadLock?

  • If two threads are waiting for each other forever, such a type of infinite waiting is called deadlock.
  • The synchronized keyword is the only reason for the deadlock situation. Hence while using synchronized keywords we have to take special care.
  • There is no resolution technique for deadlock but several prevention techniques are available.

Let’s see the following example:

Java Code
class Test {
public static void main(String args[]) throws InterruptedException {
A a = new A();
B b = new B();

MyThread1 t1 = new MyThread1(a, b);
MyThread2 t2 = new MyThread2(a, b);

t1.start();
t2.start();
}
}

class MyThread1 extends Thread {
A a;
B b;

public MyThread1(A a, B b) {
this.a = a;
this.b = b;
}

public void run() {
a.display(b);
}
}

class MyThread2 extends Thread {
A a;
B b;

public MyThread2(A a, B b) {
this.a = a;
this.b = b;
}

public void run() {
b.display(a);
}
}

class B {
public synchronized void display(A a) {
System.out.println(“Inside class B display”);
a.print();
}

public synchronized void print() {
for (int i = 0; i < 5; i++) {
System.out.println(“Inside class B print: ” + i);
}
}
}

class A {
public synchronized void display(B b) {
System.out.println(“Inside class A display”);
b.print();
}

public synchronized void print() {
for (int i = 0; i < 5; i++) {
System.out.println(“Inside class A print: ” + i);
}
}
}
  • If you run the above example, thread t1 will enter into the waiting state to get the b’s lock, and currently, t1 holds the a’s lock.
  • Similarly, t2 will enter into the waiting state to get the a’s lock and t2 currently holds the b’s lock.
  • In the above example if we remove at least one synchronized keyword then the program will not enter into the deadlock. Hence while using the synchronized keyword we have to take special care.

What is Starvation?

  • Starvation describes a situation where a thread is unable to gain regular access to the shared object or resource and is unable to make progress. 
  • This happens when shared resources are made unavailable for long periods by “greedy” threads. 
  • For example, suppose an object has a synchronized method that often takes a long time to return. If one thread invokes this method frequently, other threads that also need frequent synchronized access to the same object will often be blocked.
  • This means, unlike deadlock, starvation means long waiting of the thread where waiting ends at some certain time when the thread gets the lock of the object.

What is Livelock?

  • A thread often acts in response to the action of another thread. If the other thread’s action is also a response to the action of another thread, then livelock may result.
  • As with deadlock, livelocked threads are unable to make further progress. However, the threads are not blocked — they are simply too busy responding to each other to resume work. 
  • Example: Two people attempting to pass each other at door.

-A blog by Shwetali Khambe

Related Posts