为什么在抛出异常之后,ScheduledExecutorService不再运行任务? [英] Why does a ScheduledExecutorService not run a task again after an exception is thrown?

查看:692
本文介绍了为什么在抛出异常之后,ScheduledExecutorService不再运行任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为执行定期任务,我查看了 计时器 ScheduledThreadPoolExecutor (单线程),并决定使用后者,因为在对Executors.newSingleThreadScheduledExecutor() 的引用,它说: p>

For executing periodical tasks, I looked at Timer and ScheduledThreadPoolExecutor (with a single thread) and decided to use the latter, because in the reference for Executors.newSingleThreadScheduledExecutor(), it says:


请注意,如果此单线程由于在关闭之前的执行过程中发生故障而终止,则如果需要执行后续操作,则新的线程将占用它任务。

Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.

我的计划是使用这个作为一个保护措施来防止看门狗代码中的未捕获的异常,我想监视其他操作。我想确保并写下下面的测试,这一切都失败了。似乎我在做错误的假设,或者我的测试有问题吗?

My plan was to use this as a safeguard against uncaught exceptions in a watchdog piece of code that I want to monitor other operations. I wanted to make sure and wrote the test below, which promptly failed. It seems I was making wrong assumptions, or is something wrong about my test?

这里是代码:

@Test
public void testTimer() {
    final AtomicInteger cTries = new AtomicInteger(0);
    final AtomicInteger cSuccesses = new AtomicInteger(0);

    TimerTask task = new TimerTask() {
        @Override
        public void run()
        {
            cTries.incrementAndGet();
            if (true) {
                throw new RuntimeException();
            }
            cSuccesses.incrementAndGet();
        }
    };

    /*
    Timer t = new Timer();
    t.scheduleAtFixedRate(task, 0, 500);
     */
    ScheduledExecutorService exe = Executors.newSingleThreadScheduledExecutor();
    exe.scheduleAtFixedRate(task, 0, 500, TimeUnit.MILLISECONDS);
    synchronized (this) {
        try {
            wait(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }
    exe.shutdown();
    /*
    t.purge();
     */
    Assert.assertEquals(cSuccesses.get(), 0);
    Assert.assertTrue(cTries.get() > 1, String.format("%d is not greater than 1. :(", cTries.get()));
}


推荐答案

一旦重复的任务抛出一个未捕获的异常,死亡或处于错误状态,它有点麻烦,它也会默默地失败,除非你检查未来获得错误/异常。

Once a repeating task has thrown an uncaught exception it is assumed to have died or be in an error state. It is a bit of a gotcha that it also fails silently unless you examine the Future to get the Error/Exception.

你必须抓住例外,如果你不想杀死重复的任务。

You have to catch Exceptions if you don't want to kill the repeating task.

as matt b指出上面的评论,


这样的框架代码假设它可以安全地重新启动失败的工作将是有问题的 - 事实上它失败了一个异常意味着数据可能已经处于任何状态,并且可能重新启动该作业是不安全的。

it would be problematic for framework code like this to assume it can safely restart a failed job - the fact that it failed with an exception means that the data might have been left in any sort of state, and potentially it would be unsafe to restart the job.

这篇关于为什么在抛出异常之后,ScheduledExecutorService不再运行任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆