5

我试图弄清楚如何消除我在 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
  }
}

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

如果我在运行循环中等待或休眠,函数调用是否仍会按预期工作?(我不确定如何测试它是否 100% 有效)。

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

4

3 回答 3

2

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

代码不会仅仅因为方法是在 runnable 的实现上定义的,就“在线程上”运行。

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

于 2012-06-14T05:31:58.370 回答
2

做这样的事情

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

      }
    }

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

于 2012-06-14T05:36:01.183 回答
0

如果无事可做,则您的线程不需要存在。

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
            }
        });
    }
}
于 2012-06-14T07:23:19.443 回答