The docs for scheduleAtFixedRate and scheduleWithFixedDelay say that:
If any execution of the task encounters an exception, subsequent executions are suppressed
Assuming that my tasks were designed to do some network job and the host was not found. Will the tasks not be executed again ? It may happen that the host is back online the next moment.
Assuming what the docs were talking about was an instance of RuntimeException, like array index out of bounds, will tasks will never ever be executed again ? What if I want them to keep executing ?
will tasks will never ever be executed again?
That's what "subsequent executions are suppressed" means, isn't it?
What if I want them to keep executing ?
Don't let RuntimeExceptions and Errors escape from them.
Check about uncatched exceptions inside Runnable action, that you execute by Scheduler. By default JVM don't catch them and thread crashed unnoticed.
I suggest to use custom ScheduledThreadPoolExecutor, like this:
static class MyScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {
public MyScheduledThreadPoolExecutor(int corePoolSize,ThreadFactory threadFactory) {
super(corePoolSize, threadFactory);
}
@Override
public ScheduledFuture<?> schedule(Runnable command, long delay,TimeUnit unit) {
return super.schedule(new SheduleExceptionCatcher(command), delay, unit);
}
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay, long period, TimeUnit unit) {
return super.scheduleAtFixedRate(new SheduleExceptionCatcher(command), initialDelay, period, unit);
}
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,long initialDelay, long delay, TimeUnit unit) {
return super.scheduleWithFixedDelay(new SheduleExceptionCatcher(command), initialDelay, delay, unit);
}
/** Wrap for Runnable - for error catching */
private static class SheduleExceptionCatcher implements Runnable {
private Runnable task;
public SheduleExceptionCatcher(Runnable task) {
this.task = task;
}
@Override
public void run() {
try {
task.run();
} catch (Throwable e) {
System.err.println("" + e); // or some logger probably
}
}
}
}
And make some test:
public static void main(String[] args) {
new MyScheduledThreadPoolExecutor(2, new PriorityThreadFactory("GeneralSTPool", Thread.NORM_PRIORITY)).scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
throw new RuntimeException("Test Error");
}
},3000, 3000, TimeUnit.MILLISECONDS);
while (true){}
}
Will print
java.lang.RuntimeException: Test Error
java.lang.RuntimeException: Test Error
java.lang.RuntimeException: Test Error
java.lang.RuntimeException: Test Error
java.lang.RuntimeException: Test Error
So your task will execute forever in spite of throwings error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With