2011-12-27 31 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

相关问题