Interthread Communication | Polling in Java - Walking Techie

Blog about Java programming, Design Pattern, and Data Structure.

Sunday, October 23, 2016

Interthread Communication | Polling in Java

Prerequisite: Multithreading in java, synchronization at object level, synchronization at class level

What is Polling?

Process of testing some condition repeatedly until its true is know as polling.

Polling is usually implemented by a loop that is used to check some condition repeatedly. Once the condition is true, appropriate action is taken. This wastes CPU time.

For example, consider the classic queuing problem where one thread is producing some data and another thread is consuming it.

Problem with Polling

To understand polling problem, Lets understand classic queuing problem in details. suppose that the producer has to wait until the consumer is finished before it generates more data. In a polling system, the consumer would waste many CPU cycles while it waited for the producer to produce. Once the producer was finished, producer would start polling, wasting more CPU cycles waiting for the consumer to finish, and so on. Clearly, this situation is undesirable.

Let's see producer consumer problem using polling concept. Here we are assuming that we have one producer thread and one consumer thread, consumer thread start consuming produced data once producer produced 10 data. Here main focus is to understand the polling concept in detail.

package com.walking.techie;

import java.util.ArrayList;
import java.util.List;

public class Producer implements Runnable {
 List<Integer> sharedList;
 boolean isProduced = false;

 public Producer() {
  sharedList = new ArrayList<Integer>();
 }

 @Override
 public void run() {
  // if shared list is empty , producer will add data into shared list
  if (!isProduced) {
   for (int i = 1; i <= 10; i++) {
    sharedList.add(i);
    System.out.println("Produced: " + i);
    //sleep for 1 second
    try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  }
  System.out.println("Production is over");
  //once production is over make isProduced true
  isProduced = true;

 }
}
package com.walking.techie;

public class Consumer implements Runnable {
 Producer producer;

 public Consumer(Producer producer) {
  this.producer = producer;
 }

 @Override
 public void run() {
  // if production is not over then wait for production to over. thread
  // will wake up after every 4 seconds to check production is completed or not
  while (!producer.isProduced) {
   try {
    Thread.sleep(4000);
    System.out.println("consumer thread waked up after 4 seconds");
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  // once production is over, consumer will start consuming the data
  for (int i = 1; i <= 10; i++) {
   System.out.println("consume: " + producer.sharedList.remove(0));
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }

  System.out.println("consumption is over");
 }
}
package com.walking.techie;

public class producerConsumerDemo {
 public static void main(String[] args) {
  Producer producer = new Producer();
  Consumer consumer = new Consumer(producer);
  Thread producerThread = new Thread(producer);
  Thread consumerThread = new Thread(consumer);
  consumerThread.start();
  producerThread.start();
 }
}

Output of above program is shown below:

Produced: 1
Produced: 2
Produced: 3
Produced: 4
consumer thread waked up after 4 seconds
Produced: 5
Produced: 6
Produced: 7
Produced: 8
consumer thread waked up after 4 seconds
Produced: 9
Produced: 10
Production is over
consumer thread waked up after 4 seconds
consume: 1
consume: 2
consume: 3
consume: 4
consume: 5
consume: 6
consume: 7
consume: 8
consume: 9
consume: 10
consumption is over

In the above example of polling, the consumer thread is checking condition at every four seconds until procedure thread has completed production. Consumer thread keep checking condition at every four seconds this leads to waisting CPU cycle.

How java multi threading solve Polling Problem?

To avoid polling, Java includes an elegant inter-process communication via the wait() , notify(), and notifyAll()methods. All these method are final and belong to Object class.

All of these methods can be called only within synchronized context.

Methods Description
wait() It tells the calling thread to give up the monitor(lock) and go to sleep until some other thread enters the same monitor and calls notify( ) or notifyAll( ).
notify() It wakes up a thread that called wait( ) on the same object.
notifyAll() It wakes up all the threads that called wait( ) on the same object. One of the threads will be granted access.

Declaration of all three methods in Object class:

final void wait( ) throws InterruptedException
final void notify( )
final void notify All( )

Important point: Oracle recommends call to wait() should take place within a loop that checks the condition on which the thread is waiting.

why? , Although wait() normally wait until notify() or notifyAll() called, there is a possibility that in very rare cases the waiting thread could be awakened due to a spurious wakeup. In this case, a waiting thread resumes without notify() or notifyAll() having been called.

No comments :

Post a Comment