每次收到后端消息时,我都会将其添加到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 :(得分: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();
}
}