0

I have to schedule a method to be executed when starting and periodically thereafter at intervals of 1 minute.

For that I have done this:

public void init(){
    loadConfig(); //method which needs to be executed periodically

    Timer scheduler = new Timer();
    scheduler.scheduleAtFixedRate(loadConfig(),60000,60000);
}

This is giving an error and it should since the first parameter of scheduleAtFixedRate is of type Runnable.

What I need advice on, is how to make my loadConfig method Runnable and still have it executed when I do loadConfig() before the scheduler starts.

As of now code structure is as follows:

public class name {
    public void init() {
        ...
    }
    ...
    public void loadConfig() {
        ...
    }
}

EDIT: This is what I have already tried

public void init(){
    loadConfig();

    Timer scheduler = new Timer();
    scheduler.scheduleAtFixedRate(task,60000,60000);
}

final Runnable task = new Runnable() {
    public void run() {
        try {
            loadConfig();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
};
Lii
  • 11,553
  • 8
  • 64
  • 88
aayush_v20
  • 193
  • 1
  • 9
  • 22
  • 1
    What scheduler are you using? Have you googled what a `Runnable` is? – Evan Knowles Jun 15 '15 at 07:21
  • I did and as such wrote the code which I have added in my edit. But its still giving an error even though the docs clearly state the parameters as such: scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) – aayush_v20 Jun 15 '15 at 07:34
  • 3
    if the docs specify 4 parameters and you only give 3, it clearly won't compile – muued Jun 15 '15 at 07:36
  • And yet eclipse provides the following hint : The method scheduleAtFixedRate(TimerTask, long, long) in the type Timer is not applicable for the arguments (Runnable, int, int, TimeUnit). As such I assumed the last argument is optional. – aayush_v20 Jun 15 '15 at 07:41
  • There's no such thing as an optional argument in Java. – Evan Knowles Jun 15 '15 at 07:45
  • 1
    I guess you are using the wrong docs. What kind of timer are you using? What kind of docs are you using? – muued Jun 15 '15 at 07:45
  • Thanks @muued for directing me in the correct direction. Docs were fine but docs were of ScheduledExecutorService while I was using a simple Timer in java. Runnable now works. – aayush_v20 Jun 15 '15 at 09:13

2 Answers2

3

Using the following syntax you can create a lambda expression, which will evaluate to an object of type Runnable. When the run method of that object is called the loadConfig method will get called.

scheduler.scheduleAtFixedRate(() -> loadConfig(), 60, 60, TimeUnit.SECONDS);

Lambda expressions is a new Java 8 feature.

In this case it works like this: The arrow, ->, makes the expression into a lambda. () is the argument list, which is empty because there are no argument to the run method. The loadConfig() after the arrow is the body, which works the same way as a method body.

Since scheduleAtFixedRate expects a Runnable as a parameter, that will be the target type of the expression and the lambda will become an object of that type.

Lii
  • 11,553
  • 8
  • 64
  • 88
  • This looks like a very neat solution. Thanks. I'll need to learn more about Lambda expressions to understand this solution I guess. – aayush_v20 Jun 15 '15 at 07:38
  • @aayush_v20: They are very neat indeed! I added a bit of explanation. – Lii Jun 15 '15 at 07:47
  • Which `Timer` class is that? The `java.util.Timer` one doesn't have an overload of `scheduleAtFixedRate` accepting 4 parameters... – Itai Apr 29 '17 at 08:46
  • @sillyfly: I don't know! It is a mystery! I think, when I answered this I just assumed that the poster had the types sorted out correctly, so I showed how to used a lambda to instead of an anonymous class to do what they want. I guess they never checked that the code worked before accepting. It is very confusing for readers to have code here that doesn't work. I should fix this answer or delete it. – Lii Apr 29 '17 at 10:48
1

Since Runnable is an interface, you need to supply an object that implements that interface. The easiest way (not necessarily the cleanest) would be to write an anonymous inner class that implements that interface.

As you write that object, you'll see you have to implement the run() method. In that method you can simply call the loadConfig() method of the surrounding object.

mthmulders
  • 9,483
  • 4
  • 37
  • 54
  • 1
    Thanks for the help. Unfortunately this is what I already tried (my bad that I didn't include this attempt in my post earlier) and its still giving an error. I don't understand as to why a runnable parameter is giving this error : The method scheduleAtFixedRate(TimerTask, long, long) in the type Timer is not applicable for the arguments (Runnable, int, int) – aayush_v20 Jun 15 '15 at 07:36