How to use TimerTask with lambdas?
Solution 1
Noting first that Timer
is effectively an antiquated API, but entertaining your question nevertheless, you could write a small wrapper around it which would adapt the schedule
method to accept a Runnable
, and on the inside you'd turn that Runnable
into a TimerTask
. Then you would have your schedule
method which would accept a lambda.
public class MyTimer {
private final Timer t = new Timer();
public TimerTask schedule(final Runnable r, long delay) {
final TimerTask task = new TimerTask() { public void run() { r.run(); }};
t.schedule(task, delay);
return task;
}
}
Solution 2
To complete Marko Topolnik's answer about Timer
, you just have to call schedule
method with a lambda.
schedule(() -> {
System.out.println("Task #1 is running");
}, 500);
Solution 3
While Marko's answer is perfectly correct, I prefer my implementation:
public class FunctionalTimerTask extends TimerTask {
Runnable task;
public FunctionalTimerTask(Runnable task) {
this.task = task;
}
@Override
public void run() {
task.run();
}
}
public static class Task {
public static TimerTask set(Runnable run) {
return new FunctionalTimerTask(() -> System.err.println("task"));
}
}
Timer timer = new Timer(false);
timer.schedule(Task.set(() -> doStuff()), TimeUnit.SECONDS.toMillis(1));
This gives you more control over the timer, and you have a static utility class. Idealy give it a name that won't conflict with other common thread class, so not Task, Job, Timer.
Related videos on Youtube
skiwi
Studied Computer Science at the Eindhoven University of Technology. I used to be quite experienced in working with Java and have experience in PHP/MySQL/Javascript/jQuery/CSS/HTML aswell. Nowadays I work more often with C# and have some side projects in other languages. Feel free to check what I am working at on Github or to contact me at LinkedIn.
Updated on June 04, 2022Comments
-
skiwi almost 2 years
As you hopefully know you can use lambdas in Java 8, for example to replace anonymous methods.
An example can be seen here of Java 7 vs Java 8:
Runnable runnable = new Runnable() { @Override public void run() { checkDirectory(); } };
Can be expressed as both the following ways in Java 8:
Runnable runnable = () -> checkDirectory();
or
Runnable runnable = this::checkDirectory;
This is because
Runnable
is a functional interface, having only one (abstract) public non-default method.However... For
TimerTask
we have the following:TimerTask timerTask = new TimerTask() { @Override public void run() { checkDirectory(); } };
Looks familiar, right?
Using a lambda expression does not work though, becauseTimerTask
is an abstract class, even though it has only one abstract public non-default method, it is not an interface and hence no functional interface either.
It is also not refactored into an interface with default implementations, because it carries state, so that cannot be done then.So my question: Is there any way to use lambdas when constructing the
TimerTask
?What I wanted is the following:
Timer timer = new Timer(); timer.schedule(this::checkDirectory, 0, 1 * 1000);
Instead of some ugly anonymous inner class, is there any way to make it nicer?
-
fge about 10 yearsSince you use modern features, why not go all the way and use a
ScheduledExecutorService
instead of aTimerTask
? ;) -
skiwi about 10 years@fge Well, I didn't know it existed, until now... Now I think about it, does Java not have their APIs mention that there is a newer similar feature available, when the old feature is not yet deprecated?
-
fge about 10 yearsEh, no... This is admittedly a great lack in their documentation. Similarly, they don't mention
Files
in theFile
doc;
-
-
skiwi about 10 yearsTechnically your answer is correct, however I will personally go with
ScheduledExecutorService
instead ofTimerTask
. -
krivar over 8 yearswhat's the current API then?
-
François SAMIN over 8 years
Runnable
is an interface, you can implement it with a lambda. So you can call theschedule
method with a lambda. Here is a working gist gist.github.com/fsamin/ec5aa79bc23965eca277 -
gerardw over 8 yearsMisunderstood answer; you're entirely correct of course.