gpt4 book ai didi

java - ScheduledThreadPoolExecutor 线程安全

转载 作者:行者123 更新时间:2023-12-02 08:30:54 26 4
gpt4 key购买 nike

ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 是线程安全的吗?现在,我有一个场景如下:

  • 5 ThreadPoolExecutor(s)
  • exec1(执行 JobA(A 级作业):最多 4-5 个作业的并行度),
  • exec2(执行 JobB(由每个 JobA 内的 List 组成):每个 JobA 超过 800-3000 个作业),
  • exec3(执行并准备 JobC(由每个 JobB 创建):每个 JobB 2-3 个作业)),
  • exec4(执行 JobD(每个作业 1-2 个 Activity )),
  • exec5(等待所有作业完成,然后执行某些 Activity );

(我希望上面的场景已经很清楚了)。

此外,所有执行器在对象级别都是通用的。在 A 级,最多只有 4-5 个作业并行执行,并为下一个级别 (B) 的各种单独作业/事务做准备。B 级作业反过来为 C 级准备作业,C 级为 D 级准备作业。

Exec5 是一个持久器,它将所有数据保存到数据库中。

问题在于,作业在 C 级和 D 级的某个地方丢失,特别是当有许多并发线程尝试在后续执行程序任务列表中异步推送新作业时。没有一个 RejectionHandler 也收到任何被拒绝的处理程序。另外,如果每个 ThreadPoolExecutors 都减少为单个线程池执行器(仅 1 个线程),我不会遇到任何问题。这些作业本质上非常小,因此并行性确实为该 Activity 提供了显着的优势。

我希望我已经说清楚了。

请指教。问候,KT

最佳答案

您如何向 ExecutorService 提交工作?您使用的是submit(Callable)还是execute(Runnable)?在前一种情况下,调用代码有责任通过在返回的 Future 上调用 get() 来检测任何异常情况。因此,如果您的执行器只是将工作传递给下一个执行器并丢弃 Future ,则任何错误都不会被检测到。

一种解决方法是使用 execute(Runnable) 并重写 ThreadPoolExecutorafterExecute(Runnable r, Throwable t) 方法来引发如果使用非空 Throwable 调用,则发出警报。

另一种解决方案是将执行器包装在 CompletionService 中,并使用专用线程删除已完成的 Future 并“提取”和异常。

顺便说一句,这个架构看起来相当复杂。 5级执行者真的有必要吗?为什么不从执行所有必需步骤的单个 ThreadPoolExecutor 开始呢?您的设计越简单,就越容易发现任何问题。

关于java - ScheduledThreadPoolExecutor 线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3372325/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com