繁体   English   中英

如何通过回调函数避免Java Thread中的繁忙循环

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

我试图找出如何消除我在Java中的线程中的繁忙循环。 该线程只会等待Listener类的回调。 线程类看起来像这样:

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
  }
}

我试图让这段代码尽可能简单。 想法是Listener正在等待从串行端口接收一些数据,并且当收到消息时,线程将对其进行一些处理。 我更喜欢使用一些同步变量,如Message的BlockingQueue,但我无法修改Listener代码。 当然,问题是运行循环会占用处理器周期。 我的问题:

如果我在运行循环中等待或睡眠,函数调用是否仍然按预期工作? (我不确定如何测试这种方法100%的工作时间)。

有没有更好的方法来完全避免这种循环?

做这样的事情

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()
                }

      }
    }

获得事件后,您将更新某些状态/存储消息并释放通知线程。 然后从你的线程处理事件

仅仅根据您发布的内容,看起来有人误解了线程是什么以及它是如何工作的。 如果while(true){}内部确实没有任何内容,并且不是因为简洁而将其剪切掉,那么在此线程上实际上不会处理该消息。

代码并不 “上线程”跑只是因为方法上可运行的实现定义。

调用messageReceived(Message m)方法时,该方法的主体在调用线程中执行。 它不会仅仅因为在那里被定义而被“传递”到这个线程。

如果没有什么可做的,你的线程不需要存在。

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
            }
        });
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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