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

CopyOnWriteArrayList与newScheduledThreadPool配合异常问题排查

问题原因分析

核心问题出在两个关键点上:

  • CopyOnWriteArrayList迭代器的限制:CopyOnWriteArrayList的迭代器是基于容器的快照生成的,它天生不支持修改操作(包括remove())。当你调用iterator.remove()时,会直接抛出UnsupportedOperationException。
  • 定时任务的异常处理规则:你的定时任务里把这个异常包装成RuntimeException抛出,但整个任务没有捕获该异常。根据ScheduledExecutorService的运行规则:如果重复执行的定时任务抛出未捕获的异常,后续所有的定时执行都会被直接终止,这就是为什么你的任务只执行了一次就停了。

移除iterator.remove()后正常的原因:

去掉这条语句后,定时任务里不再触发异常,任务就能按照你设定的5秒间隔持续执行下去。

修复删除元素的正确方式:

如果需要完成"移除已完成任务"的逻辑,不能用迭代器的remove(),可以改用批量删除的方式,比如:

scheduledExecutorService.scheduleAtFixedRate(() -> {
    List<FactRec> completedTasks = new ArrayList<>();
    // 先遍历收集已完成的任务
    for (FactRec curr : list) {
        if(curr.f.isDone()){
            try {
                System.out.println("\n------------------------------");
                System.out.printf("%d! = %s%n", curr.num, curr.f.get());
                System.out.println("------------------------------");
                completedTasks.add(curr);
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        } else{
            System.out.println("Task is still running");
        }
    }
    // 批量移除已完成的任务
    list.removeAll(completedTasks);
}, 0, 5, TimeUnit.SECONDS);

内容的提问来源于stack exchange,提问作者Cody

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:22:02