如何堆叠传入的数据

Posted

技术标签:

【中文标题】如何堆叠传入的数据【英文标题】:How to stack up incoming data 【发布时间】:2012-01-28 10:54:28 【问题描述】:

每次收到后端消息时,我都会将其添加到 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 休眠时堆叠消息。但似乎 Thread.sleep 停止了一切,而不仅仅是当前线程。

谢谢

【问题讨论】:

嗨,你为什么要等这么久?您不能将传入消息堆叠在 messageReceived 事件的列表中吗?如果您使用的是多线程应用程序,您应该考虑添加一些同步锁来保证数据的一致性。 【参考方案1】:

您正在使用 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();
    

【讨论】:

非常感谢!我已经修改代码好几个小时了,没有看到这么明显的错误。 希望你能看到这是一个更容易修改和控制的结构(并且它的线程安全)

以上是关于如何堆叠传入的数据的主要内容,如果未能解决你的问题,请参考以下文章

如何根据条件行值对 pandas 数据框进行取消堆叠或取消透视?

Origin如何做堆叠面积图

如何在R中堆叠数据框[重复]

使用自动布局 VFL 垂直堆叠一组按钮

R通过时间维度堆叠栅格数据

如何合并熊猫数据框中的两列,堆叠在顶部