简体   繁体   中英

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?

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

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.

If there is nothing to do your thread doesn't need to exist.

class AsyncMessageListener implements MessageListener{
    private final Listener listener;
    private final ExecutorService services = Executors.newSingleThreadExecutor();

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

    public void messageReceived(final Message m){
        services.submit(new Runnable() {
            @Override
            public void run() {
                // process message m
            }
        });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM