Позволить потоку SwingWorker спать

1

У меня есть GUI Swing, который должен периодически читать 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() в SwingWorker), я теперь запутался, если это было хорошей идеей. Я собрал то, что вы обычно не пропускаете фоновый поток, потому что система позаботится об этом.

Однако в моем случае этот метод кажется мне полезным.

Может ли кто-нибудь уточнить возможные проблемы с этой реализацией?

Любой вход оценивается. Это касается конкретной темы, а также общего дизайна. Если я делаю что-то неправильно, я хочу это знать. :)

Приветствую

  • 0
    SwingWorker (несмотря на то, что этот форум любит SwingWorker) не очень хорошая идея, я бы посоветовал использовать стандартный (простой, управляемый, настраиваемый по сравнению с SwingWorker) Runnable # Thread
Теги:
multithreading
swing
swingworker
rss-reader

2 ответа

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);
        }
    }
}
  • 0
    неправильный ответ - doInBackground () является переходом к рабочему потоку, затем по умолчанию никогда не уведомлял EDT, подробнее в учебнике Oracle Concurency в Swing - часть о потоке диспетчеризации событий (метод чтения подсказок, используемый ratchet freak)
1

Исполнитель swing (на моей машине отладки) запускает только 10 потоков для всех SwingWorkers. Это означает, что если 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);
    }
}
  • 0
    1. этот вопрос не отвечает, 2. процесс без публикации не является ответом, пустой совет для OP, 3. 10 потоков для всех SwingWorkers ???, не правда, но 12-й. (одновременно запущенный) может генерировать бесконечную ошибку для SwingWorker (не представлен во всех JDK)
  • 0
    @mKorbel, вызывающий execute для свингворкера, отправляет его на ExecutorService по умолчанию, если он не существует, то он создает нового исполнителя ThreadPool с maximumPoolsize = 10 . Вы все еще можете отправить его своему собственному исполнителю (с потенциально большим количеством потоков) без проблем.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню