Han*_*etz 24 java error-handling threadpool
为了执行定期任务,我查看Timer并ScheduledThreadPoolExecutor(使用单个线程)并决定使用后者,因为在其中reference for Executors.newSingleThreadScheduledExecutor(),它说:
但请注意,如果此单个线程由于在关闭之前执行期间的故障而终止,则在需要执行后续任务时将使用新的线程.
我的计划是使用它作为一个保护措施,以防止我希望监视其他操作的监视程序代码中未被捕获的异常.我想确认并编写下面的测试,这很快就失败了.看来我做错了假设,或者我的测试有些不对劲?
这是代码:
@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()));
}
Run Code Online (Sandbox Code Playgroud)
Pet*_*rey 26
一旦重复任务抛出未捕获的异常,就会假定它已经死亡或处于错误状态.除非你检查Future以获得错误/异常,否则它也会无声地失败.
如果您不想杀死重复任务,则必须捕获异常.
正如亚光b在上面的评论中指出的,
对于像这样的框架代码来说,假设它可以安全地重新启动失败的作业,这将是一个问题 - 它因异常而失败的事实意味着数据可能已经处于任何类型的状态,并且可能重新启动它是不安全的.工作.
亚特b给出了原因.
对于像这样的框架代码来说,假设它可以安全地重新启动失败的作业,这将是一个问题 - 它因异常而失败的事实意味着数据可能已经处于任何类型的状态,并且可能重新启动它是不安全的.工作.
应该注意的是,它写在ScheduledExecutorService的文档中
如果任务的任何执行遇到异常,则后续执行被禁止.
正如 Michael Krusse所说,关于创建新线程的观点是允许其他任务继续运行.
| 归档时间: |
|
| 查看次数: |
15326 次 |
| 最近记录: |