2015-04-01 105 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); 
    } 
} 

我对让线程睡眠想法是减少GET的数量。我的程序不需要每毫秒更新一次以减少服务器负载我认为这将是一个好主意。

看完这个问题之后(java - thread.sleep() within SwingWorker)我现在很困惑,毕竟这是个好主意。我收集的是,通常不会让后台线程进入睡眠状态,因为系统会照顾它。

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

有人可以详细说明这个实现的可能的问题吗?

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

问候

+0

SwingWorker的(尽管事实上,本次论坛爱的SwingWorker )是不好的主意,我会建议使用标准(简单,可管理,可与SwingWorker比较)可运行#线程 – mKorbel 2015-04-01 17:14:46

回答

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); 
     } 
    } 
} 
+0

错误的答案 - doInBackground()brigde工作线程,然后默认情况下从未通知EDT,更多在Swing中的Oracle教程Confectionncy中 - 关于事件调度线程的一部分(提示棘轮怪胎使用的读取方法) – mKorbel 2015-04-01 17:08:33

1

摆动执行人(我调试的机器上)唯一的火灾为所有SwingWorkers提供10个线程。这意味着如果有10个任务正在休眠,那么在一个任务返回之前不能再开始任何任务。您可以将SwingWorker提交给任何执行程序进行处理,而不是依赖默认执行程序。

。在你的代码中的另一个问题,即你从另一个线程而应该publish对访问GUI对象和使用过程中的方法来处理它:

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.所有SwingWorkers ??? 10个线程,不是真的,但是12。 (并发运行)可能会为SwingWorker生成无尽的bug(未在所有JDK中提供) – mKorbel 2015-04-01 17:12:18

+0

@mKorbel在swingworker上调用'execute'将其提交给默认的ExecutorService,如果它不存在,那么它将创建一个新的ThreadPool执行程序,其中包含'maximumPoolsize = 10'。你仍然可以将它提交给你自己的执行者(可能有更多的线程)没有问题。 – 2015-04-02 08:27:50