使用计时器启动SwingWorker?

时间:2011-05-16 09:56:12

标签: java concurrency timer while-loop swingworker

我需要执行的任务包括从外部服务器请求一些数据,对数据执行一些(相当冗长的)处理,然后使用处理结果更新GUI。由于服务器可能没有响应,因此该任务非常适合SwingWorker:doInBackground()方法获取结果,然后done方法更新GUI。

我需要每隔几秒发生一次。我知道我可以使用while循环和Thread.sleep,并在每次睡眠后创建一个新的SwingWorker。但是我读到的一切都在使用循环和睡眠时皱眉。我想使用计时器但是:

  • 使用挥杆计时器似乎适得其反;因为他们在EDT上运行,我基本上没有理由使用SwingWorker的doInBackground方法。如果服务器没有响应,则GUI将无响应。

  • 使用java.util.Timer似乎有点浪费:它似乎为TimerTask()创建了一个后台线程,因为我只是创建一个SwingWorker来完成实际的工作,我实际上是在创建一个创建另一个后台线程的后台线程。

谁能告诉我什么是最好的解决方案?我想坚持使用SwingWorker,因为它似乎非常适合任务,但如果我能帮助它,我想避免使用while循环。

由于

4 个答案:

答案 0 :(得分:2)

您可以使用ScheduledExecutorService

scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) 

// get a scheduled executor service with one thread
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
// schedule the worker at an intervall of 5 seconds
scheduler.scheduleAtFixedRate(myWorker, 0, 5, TimeUnit.SECONDS);

答案 1 :(得分:2)

我不明白为什么你不能使用Swing Timer来启动Swing Worker。你有什么尝试?

答案 2 :(得分:1)

我认为你正在使用SwingWorker走上正轨。现在您需要查看其发布和处理方法。随着处理的进行,你从后台线程发布()一个对象,然后在Swing(EDT)线程上调用process()方法,这样你就可以更新gui。

这种方式没有一堆定时器和其他线程可以协调。

javadocs有一个简单的素数示例: http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html

答案 3 :(得分:0)

您要检索的数据集有多大?如果它相当小,我将完全分离获取/处理和显示的任务。

  1. 使用某种内存缓存来保存最近处理的数据集。
  2. 使用javax.swing.Timer使用缓存数据更新GUI。
  3. 使用java.util.Timer从数据库中获取数据,处理数据并更新缓存。
  4. 请注意缓存上两次的同步问题。你不希望你的摇摆计时器在另一个计时器正在更新它的同时抓取数据。