April 17, 2024

Thread Starvation in Java

In a multi-threaded environment access to shared resources is synchronized so that at any given time only a single thread can enter a synchronized context. Theoretically all the threads trying to gain access to a synchronized block or method should get some CPU time periodically but in practice that may not happen. If a thread is unable to gain regular access to shared resources and is unable to make progress it is called thread starvation in Java multi-threading.

Why does thread starvation happen

Thread starvation may happen because of the following reasons.
  1. Suppose an object has a synchronized method that requires some heavy processing and takes 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.
  2. Threads with higher priority are scheduled to run first and taking all the CPU time causing the thread with minimum priority to keep on waiting to be scheduled to run.
  3. In a synchronized context even if wait method is used to relinquish object’s lock, one of the waiting thread never gets a chance to enter the synchronized context as some other threads are notified and scheduled to run.

Thread starvation Java Example

Let us try to create a scenario when thread starvation in Java may happen using the reasons as stated above.

In the code thread t1 has been assigned the maximum thread priority and it calls the synchronized method thrice. Where as thread t2 has been assigned the minimum thread priority and it calls the synchronized method only once but it has to wait for all the three calls of thread t1 to execute the synchronized method.

class MyRunnable implements Runnable{
  ThreadDemo td;
  MyRunnable(ThreadDemo td){
    this.td = td;
  }
  @Override
  public void run() {
    td.testMethod();
    td.testMethod();
    td.testMethod();
  }	
}

class AnotherRunnable implements Runnable{
  ThreadDemo td;
  AnotherRunnable(ThreadDemo td){
    this.td = td;
  }
  @Override
  public void run() {
    td.testMethod();
  }	
}

public class ThreadDemo {
  public synchronized void testMethod(){
    try {
      System.out.println("Doing some heavy processing for thread " + 
        Thread.currentThread().getName());
      Thread.sleep(300);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
	
  public static void main(String[] args) {		
    ThreadDemo td = new ThreadDemo();
    Thread t1 = new Thread(new MyRunnable(td), "t1");
    Thread t2 = new Thread(new AnotherRunnable(td), "t2");

    t1.setPriority(Thread.MAX_PRIORITY);
    t2.setPriority(Thread.MIN_PRIORITY);

    t1.start();
    t2.start();
  }
}
Output
Doing some heavy processing for thread t1
Doing some heavy processing for thread t1
Doing some heavy processing for thread t1
Doing some heavy processing for thread t2

That's all for the topic Thread Starvation in Java. 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