让SwingWorker线程休眠

时间:2015-04-01 15:48:49

标签: java multithreading swing swingworker rss-reader

我有一个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)我现在很困惑,毕竟这是一个好主意。我收集的是你通常不会让后台线程睡眠,因为系统会处理它。

然而在我的情况下,这种方法似乎对我有益。

有人可以详细说明此实施的可能问题吗?

任何输入都表示赞赏。这适用于特定主题以及一般设计。如果我做错了什么我想知道它。 :)

问候

2 个答案:

答案 0 :(得分:1)

使用ScheduledExecutorService:

ScheduledExecutorService ses = Executors.newSingleScheduledExecutorService();
ses.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        doInBackground();
    }
}, 10, TimeUnit.SECONDS);

摆脱Thread.sleepwhile(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);
    }
}