Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I avoid busy loop in Java Thread with callback function

I am trying to figure out how to eliminate a busy loop in a thread I have in Java. The thread does nothing but wait for a callback from the Listener class. The thread class looks something like this:

class MyThread implements Runnable, MessageListener{
  private Listen Listener;

  public MyThread(){
    Listener = new Listener(this);
  }

  public void run(){
    while(true){}
  }

  public void messageReceived(Message m){
    //do stuff
  }
}

I have tried to make this code as simple as possible. The idea is that Listener is waiting to receive some data from a serial port and when a message is received the thread will do some processing on it. I would prefer to use some synchronized variables such as a BlockingQueue of Message but I can't modify the Listener code. The issue, of course, is that the run loop eats up processor cycles. My questions:

If I wait or sleep in the run loop will the function call still work as expected? (I'm not sure how to test that this works 100% of the time).

Is there some better way to avoid this loop altogether?

like image 961
Newlyn Erratt Avatar asked Oct 08 '22 13:10

Newlyn Erratt


2 Answers

Do something like this

class MyThread implements Runnable, MessageListener{
          private Listen Listener;
          private Object lock = new Object();
      public MyThread(){
        Listener = new Listener(this);
      }

      public void run(){
        while(true){
            synchronized (lock) {
                try{
                    lock.wait();
                    // use the updated status
                }catch (Exception e) {
                    e.printStackTrace()
                }
            }
        }
      }

      public void messageReceived(Message m){
          synchronized (lock) {
                try{
                    // Do something with the message here like update some status
                    lock.notify();                      
                }catch (Exception e) {
                    e.printStackTrace()
                }

      }
    }

Once you get the event, you update some status/ store the message and release the notifying Thread. Then from your thread process the event

like image 74
bobby Avatar answered Oct 12 '22 20:10

bobby


Going just by what you're posted, it looks like someone has misunderstood what a thread is and how it works. If there really is nothing inside the while(true){} and it's not that you just clipped it out for brevity, then handling the message doesn't actually happen on this thread.

Code does not run "on a thread" just because the method is defined on the implementation of runnable.

When your messageReceived(Message m) method is called, the body of that method executes in the calling thread. It does not get 'handed off' to this thread simply by virtue of being defined there.

like image 45
Affe Avatar answered Oct 12 '22 20:10

Affe