如果出现问题并且我想重试,使用相同的 Executor 重新排队 Runnable 是否安全或明智?

发布于 2024-10-18 02:41:21 字数 452 浏览 6 评论 0原文

我刚刚在我的 runnable 的 run() 方法中编写了这段代码:

try {
    dbConnection = MyApp.datasource.getConnection();
} catch (SQLException e) {
    logger.log(Level.SEVERE, "Could not obtain a DB connection! Re-enqueuing this task. Message: " + e.getMessage(), e);
    MyApp.executor.execute(this);
    return;
}

如您所见,如果任务无法获得数据库连接,它应该将自己重新排队到它所在的同一队列中在它运行之前。

我认为这可能是安全的,但感觉很有趣,我只是想确保没有遗漏任何问题。

谢谢!

I just wrote this code in my runnable's run() method:

try {
    dbConnection = MyApp.datasource.getConnection();
} catch (SQLException e) {
    logger.log(Level.SEVERE, "Could not obtain a DB connection! Re-enqueuing this task. Message: " + e.getMessage(), e);
    MyApp.executor.execute(this);
    return;
}

As you can see, if the task can't obtain a DB connection, it should re-enqueue itself, into the same queue it was in before it ran.

I'm thinking this is probably safe, but it feels funny, and I just want to make sure there aren't any gotchyas that I'm missing.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

内心旳酸楚 2024-10-25 02:41:21

就执行者而言,这很好。

但请记住,失败可能会很快发生,然后执行器可能会快速重新运行您的代码。这可能会导致大量 CPU 消耗而没有任何结果。

内置强制重试延迟和最大循环计数。

This is fine as far as the executor goes.

But keep in mind that failures may occur pretty quickly, and then the Executor may re-run your code quickly. This can result in burning a lot of CPU for no results.

Build in forced retry delays and maximum loop counts.

等待我真够勒 2024-10-25 02:41:21
  1. 存在出现所谓的有毒消息的风险:如果SQLException无法消失,任务将无限重复。您必须提供某种计数器或计时器。

  2. 根据执行器的占用情况(已经调度了多少个并发任务),重试之间的间隔可能会有很大差异。您可能会使用 100% 的 CPU,或者等待重试很长时间。

  3. 如果偶然,您的任务(重新安排自身的任务)等待(重新安排)调用的结果,您可能会当执行器仅在一个线程上运行时,会遇到死锁。

  4. 您正在使用 MyApp 的原始字段,无论如何似乎都是一个糟糕的模式。

至于总体思路:为什么不在 run() 中有一个循环呢?您想对正在执行的其他任务更加“公平”吗?

  1. There is a risk of so called poison message to occur: the task will repeat itself infinitely if the SQLException won't get away. You must provide some sort of counter or timer.

  2. Depending on the occupancy of the executor (how many concurrent tasks are already scheduled), the interval between retries may vary significantly. You might either use 100% of the CPU or wait for retry for a very long time.

  3. If, by incident, your parent task (the one that re-schedules itself) waits for the result of the child (re-scheduled) invocation, you might experience deadlock when the executor runs on only one thread.

  4. You are using raw fields of MyApp, seems like a bad pattern whatsoever.

As for the overall idea: why not just have a loop in run()? You want to be more "fair" to other tasks being executed?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文