March 6, 2021

Livelock in Java Multi-Threading

In a multi-threaded environment 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 a livelock may happen if two or more threads are busy responding to the action of each other and unable to make further progress in the process.

If we take example of three threads where-

  1. Thread-1 is acting on a response from Thread-2
  2. Thread-2 is acting on a response from Thread-3
  3. Thread-3 is acting on a response from Thread-1

So these three threads are busy responding to the action of each other thus unable to make any progress because of livelock.

How livelock is different from deadlock

In case of livelock, just like deadlock, threads don’t make any progress but they are not blocked as the case with deadlock. Threads are active but they are busy responding to each other thus not making any progress.

Java livelock example

In the example there are two threads for customer and shop, customer is waiting for the order to be shipped before paying money where as shop is willing to ship order only after getting amount. So both threads are responding to event but busy there itself unless event condition is fulfilled.

public class ThreadLiveLock {
  static final Customer customer = new Customer();
  static final Shop shop = new Shop();
  public static void main(String[] args) {
    Thread thread1 = new Thread(new Runnable() {
      @Override
      public void run() {
        customer.payMoney(shop);	
      }
    });
    
    Thread thread2 = new Thread(new Runnable() {
      @Override
      public void run() {
        shop.shipOrder(customer);	
      }
    });

    thread1.start();
    thread2.start();
  }
}

class Customer{
  private boolean paid = false;
  public void payMoney(Shop shop){
    while(!shop.isOrderShipped()){
      System.out.println("waiting for order");
      try {
        Thread.sleep(1000);
      } catch (InterruptedException ex) {
        ex.printStackTrace();
      }
    }
    setPaid(true);
  }
  public boolean isPaid() {
    return paid;
  }
  public void setPaid(boolean paid) {
    this.paid = paid;
  }
}

class Shop{
  private boolean orderShipped = false;
  public void shipOrder(Customer customer){
    while(!customer.isPaid()){
      System.out.println("waiting for money");
      try {
        Thread.sleep(1000);
      } catch (InterruptedException ex) {
        ex.printStackTrace();
      }			
    }
    setOrderShipped(true);
  }

  public void setOrderShipped(boolean orderShipped) {
    this.orderShipped = orderShipped;
  }

  public boolean isOrderShipped() {
    return orderShipped;
  }
}
Output
waiting for order
waiting for money
waiting for money
waiting for order
waiting for order
waiting for money
waiting for money
waiting for order

That's all for the topic Livelock in Java Multi-Threading. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment