Java has the executor services to do exactly what you want to do. Have a look at the method ScheduledExecutorService#scheduleWithFixedDelay(). As opposed to the method ScheduledExecutorService#scheduleAtFixedRate(), the method with fixed delay does not try to keep up.
Here is an example:
public void run() {
Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(
this::task, 0, 10, TimeUnit.MILLISECONDS);
}
public void task() {
// run your task
}
Indeed, your use case seems to be not covered by the standard library methods. However, you should be able to use the following class to do what you want.
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
public class TimerExample {
private final ScheduledExecutorService executor = Executors
.newSingleThreadScheduledExecutor();
private final Runnable task;
private final Consumer<Exception> onException;
private final long delay;
private final TimeUnit unit;
public TimerExample(Runnable task, Consumer<Exception> onException,
long delay, TimeUnit unit) {
this.task = task;
this.onException = onException;
this.delay = delay;
this.unit = unit;
}
public void start() {
executor.execute(this::execute);
}
private void execute() {
executor.schedule(this::execute, delay, unit);
try {
task.run();
} catch (Exception e) {
onException.accept(e);
}
}
}
And here the usage:
new TimerExample(() -> System.out.println("."),
Exception::printStackTrace, 20, TimeUnit.MILLISECONDS).start();
Since it uses a single threaded executor service, it will not start the next execution until the previous is finished. Also, it schedules the next execution before the task itself is executed.
Also, see this SO-question about why you should prefer the executor services above the Timer class.
You still have to implement the shutdown mechanism by yourself.