2011-12-27 13 views
1

バックエンドメッセージが来るたびに、それをJListに追加して、fireIntervalAddedを使用してJListをリフレッシュしています。問題は、1秒後に20個のメッセージが到着し、それぞれがfireIntervalAddedを呼び出すということです。私がしたいのは、List内のすべてのメッセージをスタックし、1つの大きなデータスタックをJListに送信することです。私は、私は非常に間違って何かをやっていると思います受信データをスタックする方法

private class StackingListener implements MessageListener { 
    private List<Message> messages = new LinkedList<Message>(); 
    private int waiting = 0; 
    @Override 
    public void messageReceived(MessageEvent event) { 
     stackData(event.getData()); 
    } 

    private void stackData(Message data) { 
     messages.add(data); 
     if (waiting <= 0) { 
      waiting = 3; 
      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        while(--waiting > 0) { 
         try { 
          Thread.sleep(500); 
         } catch (InterruptedException e) { 
          e.printStackTrace(); 
         } 
        } 
        List<Message> list = new ArrayList<Message>(messages); 
        messages.clear(); 
        logger.info("Adding list with size of " + list.size()); 
        controller.getListModel().addFullElements(list); 
       } 
      }).run(); 
     } else { 
      waiting = 3; 
     } 
    } 
} 

:私の現在のソリューションは、それが常に代わりに一つの大きなスタックの一つのメッセージを送信し、動作するようには思えません。このコードのアイデアは、スレッドがスリープしている間にメッセージを積み重ねることです。しかし、Thread.sleepは現在のスレッドだけでなく、すべてを停止しているようです。

おかげ

+0

こんにちは、なぜこれをすべて待つ必要がありますか?入ってくるメッセージをmessageReceivedイベントのリストの中に積み重ねることはできませんか?マルチスレッドアプリケーションを使用している場合は、同期ロックをいくつか追加して、データの一貫性を保証することを検討する必要があります。 – Felipe

答えて

3

あなたは、現在のスレッドでrun()メソッドを呼び出しThread.run()を使用しています。あなたが意図したのは、Thread.start()がスレッドを作成し、その新しいスレッドでrun()を呼び出すことでした。

しかし、私はこのようなコードを構造化しません。私はより単純なapporachはキューを使用することだと思う。

class StackingListener implements MessageListener, Runnable { 
    private final BlockingQueue<Message> messages = new LinkedBlockingDeque<Message>(); 
    private final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); { 
     service.scheduleAtFixedRate(this, 500, 500, TimeUnit.MILLISECONDS); 
    } 

    @Override 
    public void messageReceived(MessageEvent event) { 
     messages.add(event.getData()); 
    } 

    @Override 
    public void run() { 
     final List<Message> list = new ArrayList<Message>(); 
     messages.drainTo(list); 

     logger.info("Adding list with size of " + list.size()); 
     // add to the GUI component in a thread safe manner. 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       controller.getListModel().addFullElements(list); 
      } 
     }); 
    } 

    public void stop() { 
     service.shutdown(); 
    } 
} 
+0

ありがとうございました!私は何時間も自分のコードを修正していて、そのような明白な間違いを見ることはできませんでした。 – Keynash

+0

うわー、ありがとう! – Keynash

+0

うまくいけば、これは変更と制御(そしてそのスレッドセーフ)のより簡単な構造です –

関連する問題