我有一个Swing GUI,应定期读取RSS提要(提要由我写的应用程序提供)。我已经在SwingWorker中实现了这个,并想问这是否是一个合理的设计。
以下是我为后台方法编写的代码:
@Override
protected Void doInBackground() throws Exception {
comboBoxModel.removeAllElements();
while(true) {
Channel feedChannel = webResource.path(role.role())
.accept(MyMediaType.APPLICATION_RSS)
.get(Rss.class).getChannel();
List<Item> itemList = feedChannel.getEntryList();
for(Item item : itemList) {
String itemLink = item.getLink();
if(!feedItemMap.containsKey(itemLink)) {
comboBoxModel.addElement(new Pair<>(itemLink, true));
feedItemMap.put(itemLink, true);
}
}
Thread.sleep(10000);
}
}
让线程睡眠的想法是减少GET的数量。我的程序不需要每毫秒都是最新的,所以为了减少服务器负载,我认为这是个好主意。
在阅读完这个问题后(java - thread.sleep() within SwingWorker)我现在很困惑,毕竟这是一个好主意。我收集的是你通常不会让后台线程睡眠,因为系统会处理它。
然而在我的情况下,这种方法似乎对我有益。
有人可以详细说明此实施的可能问题吗?
任何输入都表示赞赏。这适用于特定主题以及一般设计。如果我做错了什么我想知道它。 :)
问候
答案 0 :(得分:1)
使用ScheduledExecutorService:
ScheduledExecutorService ses = Executors.newSingleScheduledExecutorService();
ses.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
doInBackground();
}
}, 10, TimeUnit.SECONDS);
摆脱Thread.sleep
和while(true)
循环:
protected Void doInBackground() throws Exception {
comboBoxModel.removeAllElements();
Channel feedChannel = webResource.path(role.role())
.accept(MyMediaType.APPLICATION_RSS)
.get(Rss.class).getChannel();
List<Item> itemList = feedChannel.getEntryList();
for(Item item : itemList) {
String itemLink = item.getLink();
if(!feedItemMap.containsKey(itemLink)) {
comboBoxModel.addElement(new Pair<>(itemLink, true));
feedItemMap.put(itemLink, true);
}
}
}
答案 1 :(得分:1)
swing执行器(在我的调试机器上)只为所有SwingWorkers启动10个线程。这意味着如果10个任务正在休眠,那么在一个任务返回之前不能再启动任务。但是,您可以将SwingWorker提交给任何执行者进行处理,而不是依赖于默认执行程序。
您的代码中还有另一个问题,您从另一个线程访问gui对象,而不是publish
对,并使用流程方法来处理它:
if(!feedItemMap.containsKey(itemLink)) {
publish(itemLink);
}
public void process(List<String> strings){
for(String str: strings){
comboBoxModel.addElement(new Pair<>(str, true));
feedItemMap.put(str, true);
}
}