簡體   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