Swing Worker结合Guava RateLimiter执行过慢问题排查
问题分析与解决方案
你的核心问题是Swing Worker的doInBackground方法是单线程执行的,所以循环里的所有任务都是串行运行——必须等上一个market.initializeCandles()(API调用)完全结束,才会执行下一次循环迭代。哪怕加了RateLimiter,也只是在单线程里控制调用间隔,根本发挥不了“每秒18次并发调用”的作用,反而因为串行的API响应时间拖慢了整体速度,所以去掉RateLimiter后速度没变化。
要实现“并发执行任务+RateLimiter限流”,你需要结合线程池来处理并行任务,同时用RateLimiter控制每秒18次的API调用频率,具体步骤如下:
改进方案
- 创建线程池:用
ExecutorService创建固定大小的线程池,负责并行执行API调用任务(线程数建议根据实际情况调整,比如8~16,避免过多并发触发API的反限流机制) - 用RateLimiter控制全局调用频率:RateLimiter是线程安全的,多个线程调用
acquire()会自动排队,保证每秒最多18次许可发放 - 用CountDownLatch等待所有任务完成:确保所有API调用都执行完后,再结束Swing Worker的后台任务
- 安全更新UI:通过
publish()和process()方法在EDT线程更新进度条,避免线程安全问题
修改后的代码示例
@Override protected Boolean doInBackground() throws Exception { tickers = rc.getAll24HrPriceStatistics(); progressBar.setMaximum(tickers.size()); // 创建线程池(根据实际情况调整线程数) ExecutorService executor = Executors.newFixedThreadPool(10); // 初始化CountDownLatch,计数等于任务总数 CountDownLatch latch = new CountDownLatch(tickers.size()); for (int i = 0; i < tickers.size(); i++) { int finalI = i; String symbol = tickers.get(i).getSymbol(); executor.submit(() -> { try { // 先获取RateLimiter许可,控制每秒18次调用 rateLimiter.acquire(); Market market = new Market(screener, symbol, timeframe); market.initializeCandles(); // 执行API调用 table.addMarket(market); // 发布进度到EDT线程更新UI publish(finalI); } catch (Exception e) { // 处理API调用异常,比如打印日志或记录错误 e.printStackTrace(); } finally { // 任务完成,计数减1 latch.countDown(); } }); } // 等待所有任务执行完成 latch.await(); // 关闭线程池 executor.shutdown(); return true; } // 重写process方法,在EDT线程更新进度条 @Override protected void process(List<Integer> chunks) { // 取最后一个进度值更新(避免多次更新重复值) int latestProgress = chunks.get(chunks.size() - 1); progressBar.setValue(latestProgress + 1); // 因为i从0开始,进度要+1 }
关键说明
- 线程池大小:不要设置过大,比如如果API本身限制每秒18次调用,线程池设为10~15就足够,过多线程只会在RateLimiter处排队,浪费资源
- RateLimiter的作用:它会保证全局每秒最多发放18个许可,不管有多少线程在请求,都能严格控制调用频率
- CountDownLatch:用来阻塞
doInBackground方法,直到所有API任务都执行完成,避免Swing Worker提前结束 - UI更新安全:
publish()会把进度数据提交到EDT队列,process()在EDT线程执行,所以更新进度条不会触发Swing线程安全问题
内容的提问来源于stack exchange,提问作者BitQueen
相关产品推荐
相关产品推荐

