我正在为控制台应用程序实现GUI,我需要在指定的时间间隔内执行一些操作(例如,解析XML文件).我决定使用javax.swing.Timer和SwingWorker来确保这些操作不会使我的应用程序无响应.
我用这种方式实现了计时器:
public class DataUpdateTimer extends Timer {
private String dataFlowControllerXML = null;
private DataUpdateWorker dataUpdateWorker = null;
public class DataUpdateWorker extends SwingWorker {
private String dataFlowControllerXML = null;
DataUpdateWorker(String dataFlowControllerXML) {
super();
this.dataFlowControllerXML = dataFlowControllerXML;
}
@Override
protected Boolean doInBackground() throws Exception {
Thread.sleep(300);
return Boolean.TRUE;
}
}
public class DataUpdateIntervalListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
DataUpdateTimer timer = (DataUpdateTimer)e.getSource();
DataUpdateWorker dataUpdateWorker = timer.getDataUpdateWorker();
if (dataUpdateWorker != null)
if (dataUpdateWorker.isDone()) {
Boolean updateResult = Boolean.FALSE;
try {
updateResult = (Boolean)dataUpdateWorker.get();
} catch (InterruptedException ex) {
} catch (ExecutionException ex) {
}
dataUpdateWorker = null;
}
// Creating new worker thread here
if (dataUpdateWorker == null) {
timer.dataUpdateWorker = new DataUpdateWorker(timer.dataFlowControllerXML);
// Starting a new worker thread for parsing Data Flow Controller's XML
timer.dataUpdateWorker.execute();
return;
}
}
}
DataUpdateTimer(Integer dataUpdateInterval, String dataFlowControllerXML) {
super(dataUpdateInterval.intValue(), null);
this.dataFlowControllerXML = dataFlowControllerXML;
addActionListener(new DataUpdateIntervalListener());
}
@Override
public void stop() {
super.stop();
if (dataUpdateWorker != null) {
if (!dataUpdateWorker.isDone() || !dataUpdateWorker.isCancelled())
dataUpdateWorker.cancel(true);
}
}
}
Run Code Online (Sandbox Code Playgroud)
......并按如下方式使用:
new DataUpdateTimer(1000, dataFlowControllerXML).start();
Run Code Online (Sandbox Code Playgroud)
一切都按我的意愿运作.Timer创建一个新的SwingWorker实例并执行它.完成工作后,将创建并执行新工作程序.
我感到困惑的是,在工作者的线程完成后,我仍然可以看到它在Netbeans的调试窗口中运行(例如,作为SwingWorker-pool-3-thread-1)或在Windows任务管理器中运行(数量为线程完成后,运行线程不会减少).SwingWorker线程的数量限制为10,但让它们运行会使我感到尴尬.
在简单线程使用的情况下:
Thread th = new Thread(new Runnable() {
public void run() {
int a = 0;
}
});
th.start();
Run Code Online (Sandbox Code Playgroud)
该线程在执行后自动消失.
这个SwingWorker行为正常吗?
Mar*_*ers 11
是的,这很正常.正如线程的名称所示,swing worker的模型(后台)操作被委托给线程池.完成工作后,线程将返回到池中,以便其他工作人员可以使用它.这消除了创建/销毁线程的一些开销,这可能是昂贵的.
顺便说一下,后台线程不会永远存在.看看SwingWorker我看到的来源:
//from SwingWorker.java (c) Sun Microsystems/Oracle 2009
executorService =
new ThreadPoolExecutor(1, MAX_WORKER_THREADS,
10L, TimeUnit.MINUTES,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
Run Code Online (Sandbox Code Playgroud)
这表明线程在空闲10分钟后将死亡.