You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 22:20:41