如何堆叠传入的数据

时间:2011-12-27 10:55:45

标签: java multithreading swing sleep frontend

每次收到后端消息时,我都会将其添加到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会阻止所有内容,而不仅仅是当前线程。

由于

1 个答案:

答案 0 :(得分: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();
    }
}