2011-12-27 53 views
1

每次發送後端消息時,都會將其添加到JList,並且使用fireIntervalAdded刷新JList。問題是在一秒內可能會有20條消息到達,並且每條消息都會調用fireIntervalAdded。我想要做的是將List中的所有消息堆疊起來,並將一大堆數據發送給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 2011-12-27 11:04:41

回答

3

您正在使用Thread.run(),它只是調用在當前線程的run()方法。你打算使用的是Thread.start()創建一個線程並在該新線程中調用run()。

但是我不會像這樣構造代碼。我相信一個更簡單的方法是使用隊列。

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 2011-12-27 11:03:07

+0

WOW,非常感謝! – Keynash 2011-12-27 11:39:23

+0

希望你可以看到這是一個更簡單的結構來修改和控制(和它的線程安全) – 2011-12-27 11:41:56

相關問題