我正在为控制台应用程序实现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); } } }
…并使用如下:
new DataUpdateTimer(1000,dataFlowControllerXML).start();
一切都符合我的意愿. 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();
执行后线程自动消失.
这个SwingWorker行为是否正常?
解决方法
是的,这是正常现象.正如线程的名字所示,摆动工人的模型(后台)动作被委派为
thread pool.当工作完成时,线程返回到池中,以便其他工作人员可以使用它.这消除了创建/销毁可能昂贵的线程的一些开销.
编辑
顺便说一句,后台线程不会永远坚持下去.看看SwingWorker的源码我看到:
//from SwingWorker.java (c) Sun Microsystems/Oracle 2009 executorService = new ThreadPoolExecutor(1,MAX_WORKER_THREADS,10L,TimeUnit.MINUTES,new LinkedBlockingQueue<Runnable>(),threadFactory);
这表明线程在空闲10分钟后会死机.