Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

How to transfer Signals in Java

The article focuses on the methods shared by the objects in Java Threads to pass signals between each other and introduction to Busy(),wait(), notify() and notifyAll() methods

The main objective behind thread signalling is to enable threads so that they can send signals to each other. Also, it enables them to wait for signals from other threads.

Let us see an example of the same. Assume we have a thread 2 that might be in the wait for a signal from thread 1. This determines that we have a data that is ready to be processed.

Signalling with the help of Shared Objects

We can set the signal values in a shared object variable so that the threads can send signals to each other. We have a variable known by the name of hasDataToProcess for which the Thread 1 may set the value to True from inside a synchronized block. Coming to the other Thread i.e. Thread 2, it may read the hasDataToProcess member variable. This is done inside a synchronized block.

The below lists the example of an object that has the potential to hold such a signal: Also it holds the capacity to set and verify the signal.

Listing1: Setting the Signal Values

public class MySignal{

  protected boolean hasDataToProcess = false;

  public synchronized boolean hasDataToProcess(){
    return this.hasDataToProcess;
  }

  public synchronized void setHasDataToProcess(boolean hasData){
    this.hasDataToProcess = hasData;  
  }

}

In order for signalling to work properly, we must have both the threads to have a reference to a shared MySignal instance. On the other hand, if the reference points to different MySignal instance, the signals will not be detected by them or rather we should say they will be in capable to detect each others signals.

Busy Wait

We have two threads in our tutorial and the second thread is a now actually waiting for the data to become available for processing from the first thread. Let us take a look at the loop in which we have a second thread running in at the time of waiting for the signal from the first thread.

Listing2: Thread Waiting for The Signal

protected MySignal sharedSignal = ...

...

while(!sharedSignal.hasDataToProcess()){
  //do nothing... busy waiting
}

Note: If you noticed carefully, it can be seen that we have a while loop that keeps executing until hasDataToProcess() returns true and this is called busy waiting since the thread is busy while waiting.

wait(), notify() and notifyAll()

Busy waiting is not considered to be very effective if we talk about the CPU utilization which keeps on waiting for the signal from the thread from a long time. The things would have been different if this time had been smalls. The best would be to make the waiting thread sleep or inactive until and unless the signal is received by the thread 1. In order to overcome all this, we have a Java with an in-built wait procedure. This enables the threads to be inactive until the signals are received by the thread. The class java.lang.Object has three methods, wait(), notify(), and notifyAll(), in order to accomplish this task.

The method wait() on any object makes it inactive and when another thread calls notify() on that object, it becomes active again. The calling thread must call wait() or notify() on the object and from a synchronized block. The below code lists MyWaitNotify method that makes use of wait() and notify().

Listing3: Illustrating the Wait method

Public class MonitorObject{
}

public class MyWaitNotify{

  MonitorObject myMonitorObject = new MonitorObject();

  public void doWait(){
    synchronized(myMonitorObject){
      try{
        myMonitorObject.wait();
      } catch(InterruptedException e){...}
    }
  }

  public void doNotify(){
    synchronized(myMonitorObject){
      myMonitorObject.notify();
    }
  }
}

Explanation of the code:

  • When a thread calls notify() on an object, then the thread which is actually waiting to receive the signal is made alert. This is then permitted to execute
  • Both the waiting and notifying thread calls wait() and notify(). This is done from inside a synchronized block. A thread cannot call wait(), notify() or notifyAll() and to obtain this, the lock on the object has to be released else there would be an IllegalMonitorStateException that would be thrown.
  • Once we have a thread on the alert, the wait() call cannot be exited. But this can be overcome by the thread that is calling notify() by leaving the synchronized block.

Introduction to Missed Signals

The methods notify() and notifyAll() do not save the method calls to them. This happens in the situation when no threads are waiting when they are called and then we have the notify signal which just got lost. Hence, in case we have a thread that calls notify() before the wait() is being called by the thread to signal, the signal will be missed by the waiting thread. This may lead to a serious problem and may result in the waiting thread waiting forever. It would never wake up for the reason that the signal to wake up was missed.

In order to avoid losing signals, the same should be stored inside the signal class. In the MyWaitNotify illustration, the notify signal should be stored in a member variable inside the MyWaitNotify instance.

The below code lists the modified version of MyWaitNotify:

Listing4: Modified Version of the method MyWaitNotify

Public class MyWaitNotify2{

  MonitorObject myMonitorObject = new MonitorObject();
  boolean wasSignalled = false;

  public void doWait(){
    synchronized(myMonitorObject){
      if(!wasSignalled){
        try{
          myMonitorObject.wait();
         } catch(InterruptedException e){...}
      }
      //clear signal and continue running.
      wasSignalled = false;
    }
  }

  public void doNotify(){
    synchronized(myMonitorObject){
      wasSignalled = true;
      myMonitorObject.notify();
    }
  }
}

It is to be noticed that the doNotify() method now sets the wasSignalled variable to true before calling notify() and the doWait() method verifies the wasSignalled variable before calling wait(). On the whole, it only calls wait() in case there is no signals that was received in between the earlier doWait() call and this.

Conclusion

We have come to an end to an interesting article explaining in brief the methods how signals can be passed between different threads. Hope you liked the article.



Software Developer from India. I hold Master in Computer Applications Degree and is well versed with programming languages such as Java, .Net, C and C++ and possess good working knowledge on Mobile Platforms as well.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login