4

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

我需要每隔几秒钟发生一次。我知道我可以只使用 while 循环和 Thread.sleep,并在每次睡眠后创建一个新的 SwingWorker。但是我读过的所有内容都对使用循环和睡眠不满意。我想使用计时器,但是:

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

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

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

谢谢

4

4 回答 4

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);
于 2011-05-16T10:00:28.180 回答
2

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

于 2011-05-16T10:44:42.600 回答
1

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

这样就没有一堆计时器和其他线程需要协调。

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

于 2011-05-23T16:03:08.487 回答
0

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

  1. 使用某种内存缓存来保存最近处理的数据集。
  2. 使用 ajavax.swing.Timer用缓存的数据更新 GUI。
  3. 使用 ajava.util.Timer从数据库中获取数据,对其进行处理并更新缓存。
  4. 请注意缓存中两次之间的同步问题。您不希望您的挥杆计时器在其他计时器更新数据的同时获取数据。
于 2011-05-16T10:54:01.833 回答