Java 让一个荡秋千的人睡觉

Java 让一个荡秋千的人睡觉,java,multithreading,swing,swingworker,rss-reader,Java,Multithreading,Swing,Swingworker,Rss Reader,我有一个Swing GUI,它应该定期读取rss提要(提要由我编写的应用程序提供)。我已经在一个SwingWorker中实现了这一点,我想问一下这是否是一个合理的设计 以下是我为后台方法编写的代码: @Override protected Void doInBackground() throws Exception { comboBoxModel.removeAllElements(); while(true) { Channel feedChannel =

我有一个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);
    }
}
@覆盖
受保护的Void doInBackground()引发异常{
comboBoxModel.removeAllElements();
while(true){
Channel feedChannel=webResource.path(role.role())
.accept(MyMediaType.APPLICATION\u RSS)
.get(Rss.class).getChannel();
List itemList=feedChannel.getEntryList();
用于(项目:项目列表){
字符串itemLink=item.getLink();
如果(!feedItemMap.containsKey(itemLink)){
comboBoxModel.addElement(新对(itemLink,true));
feedItemMap.put(itemLink,true);
}
}
睡眠(10000);
}
}
我让线程睡眠的想法是减少GET的数量。我的程序不需要每毫秒更新一次,所以为了减少服务器负载,我认为这是个好主意

读完这个问题()后,我现在很困惑这到底是不是一个好主意。我收集到的信息是,您通常不会让后台线程休眠,因为系统会处理它

然而,就我而言,这种方法似乎对我有益

是否有人可以详细说明此实现可能存在的问题

欢迎您的任何意见。这适用于特定主题以及总体设计。如果我做错了什么,我想知道。:)


问候语

使用ScheduledExecutor服务:

ScheduledExecutorService ses = Executors.newSingleScheduledExecutorService();
ses.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        doInBackground();
    }
}, 10, TimeUnit.SECONDS);
然后去掉
线程。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);
        }
    }
}
protectedvoid doInBackground()引发异常{
comboBoxModel.removeAllElements();
Channel feedChannel=webResource.path(role.role())
.accept(MyMediaType.APPLICATION\u RSS)
.get(Rss.class).getChannel();
List itemList=feedChannel.getEntryList();
用于(项目:项目列表){
字符串itemLink=item.getLink();
如果(!feedItemMap.containsKey(itemLink)){
comboBoxModel.addElement(新对(itemLink,true));
feedItemMap.put(itemLink,true);
}
}
}
swing executor(在我的调试机器上)只为所有SwingWorker启动10个线程。这意味着,如果有10个任务处于休眠状态,则在其中一个任务返回之前,无法启动更多的任务。但是,您可以将SwingWorker提交给任何执行者进行处理,而不是依赖默认执行者

代码中还有另一个问题,即您从另一个线程访问gui对象,您应该
发布这对对象,并使用process方法来处理它:

    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);
    }
}
if(!feedItemMap.containsKey(itemLink)){
发布(项目链接);
}
公共作废流程(列表字符串){
for(字符串str:strings){
comboBoxModel.addElement(新对(str,true));
feedItemMap.put(str,true);
}
}

回答错误-doInBackground()是brigde to Worker线程,然后默认情况下从未通知EDT,更多信息请参见Oracle教程Swing中的Concurrency-关于事件分派线程的部分(ratchet freak使用的提示读取方法)1。这个问题没有答案。没有发布的进程没有应答,OP的提示为空,3。所有Swingworker的线程数为10,不正确,但为12。(并发运行)可能会为SwingWorker生成无尽的bug(并非在所有JDK中都显示)@mKorbel调用SwingWorker上的
execute
会在默认ExecutorService上提交它,如果它不存在,则会创建一个新的线程池执行器,其
maximumPoolsize=10
。你仍然可以将它提交给你自己的执行者(可能有更多的线程)没问题。SwingWorker(尽管这个论坛很喜欢SwingWorker)不是个好主意,我建议使用标准(与SwingWorker相比简单、可管理、可设置)Runnable#Thread