SwingWorker的doInBackground仅执行一次迭代即触发done方法
问题分析与解决方案
你的循环仅执行一次就退出,核心原因大概率是**doInBackground方法中抛出了未捕获的异常**,导致后台线程直接终止,进而触发done()方法。另外还有一处明显的Swing线程违规操作需要修正:
1. 排查隐藏异常
SwingWorker后台线程抛出的异常不会直接打印到控制台,需在done()方法中调用get()捕获并查看具体错误:
protected void done() { try { get(); // 触发后台线程的异常抛出 System.out.println("done"); } catch (Exception e) { e.printStackTrace(); // 打印异常栈,定位具体出错代码 } }
执行后就能看到问题根源——大概率是new Market(tickers.get(i).getSymbol(), timeframe)这一步出错,比如符号为空、timeframe参数非法,或是Market构造方法内部抛出了异常。
2. 修正Swing组件线程违规操作
你在后台线程中直接调用progressBar.setMaximum(tickers.size()),违反了Swing核心规则:所有Swing组件的操作必须在事件调度线程(EDT)中执行。这行代码可能抛出IllegalStateException,直接终止后台线程。
将进度条最大值的设置移到EDT中执行,比如在启动SwingWorker前处理:
// 在EDT线程中初始化进度条并启动任务 SwingUtilities.invokeLater(() -> { List<TickerStatistics> tickers = rc.getAll24HrPriceStatistics(); progressBar.setMaximum(tickers.size()); new ScreenerDataLoader().execute(); });
3. 额外注意:集合线程安全性
如果markets是普通ArrayList,虽然当前只有后台线程在添加元素,但后续若有EDT线程访问该集合,可能引发并发问题。建议改用线程安全集合(如CopyOnWriteArrayList),或在访问集合时添加同步锁。
内容的提问来源于stack exchange,提问作者BitQueen
相关产品推荐
相关产品推荐

