2015-04-01 3 views
1

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

Моя идея позволяя спать нить уменьшить количество GETs. Моя программа не должна обновляться каждые миллисекунды, поэтому для снижения нагрузки на сервер я думал, что это будет хорошей идеей.

После прочтения этого вопроса (java - thread.sleep() within SwingWorker) Я теперь смущен, если это была хорошая идея. Я собрал то, что вы обычно не пропускаете фоновый поток, потому что система позаботится об этом.

Однако в моем случае этот метод, по-видимому, полезен для меня.

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

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

Привет

+0

SwingWorker (несмотря на то, что этот форум любит SwingWorker) не очень хорошая идея, я бы предложил использовать стандартный (простой, управляемый, настраиваемый по сравнению с SwingWorker) Runnable # Thread – mKorbel

ответ

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() является бриджем для Worker Thread, а затем по умолчанию никогда не был уведомлен EDT, больше в учебнике Oracle. Совместимость в Swing - часть о событии Dispatch Thread (метод чтения подсказок, используемый трехочковым) – mKorbel

1

Размах исполнитель (на моей машине) отладки только пожары до 10 потоков для всех SwingWorkers. Это означает, что если 10 задач спят, больше никаких задач не может быть начато до тех пор, пока не вернется. однако вы можете отправить SwingWorker любому исполнителю для обработки вместо того, чтобы полагаться на исполнителя по умолчанию.

Существует еще одна проблема в вашем коде, где вы получаете доступ к объекту графический интерфейс из другого потока, вы должны вместо 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) – mKorbel

+0

@mKorbel, вызывающий 'execute' на swingworker, отправляет его в ExecutorService по умолчанию, если он не существует, то он создает нового исполнителя ThreadPool с' maximumPoolsize = 10'. Вы все равно можете отправить его своему собственному исполнителю (с потенциально большим количеством потоков) без проблем. –