ExecutorService & Lambdas - difference between .execute(() -> ...) and .execute()

ForInfinity :

I have a class, which implements the Runnable interface, and is a task that once started will run indefinitely (a long-running thread).

public class LongRunningTask implements Runnable {

    @Override
    public void run() {
        //stuff happening here
    }

}

A simple ExecutorService/ThreadPoolExecutor creation:

final ExecutorService executorService = Executors.newFixedThreadPool(8);

If the LongRunningTask is actually started/executed, I am able to observe the actual result of it, and so, I noticed this:

  • if I pass it to be executed with executorService.execute(() -> new LongRunningTask());, it will not be executed at all, and there won't be a result.

  • if I pass it to be executed with executorService.execute(new LongRunningTask()); it will be executed just as it should be and there will be a result.

What's the difference when using the lambda syntax of () ->?

Sweeper :

execute accepts a Runnable and then calls its run method at some point.

In your question, you demonstrated two ways of passing execute a Runnable:

  • passing an object that implements Runnable:

    executorService.execute(new LongRunningTask());
    
  • passing a lambda expression that accepts no arguments:

    executorService.execute(() -> new LongRunningTask());
    

In the first case, new LongRunningTask().run() would be called. Presumably, this is a method you implemented in //stuff happening here. That's the code you want to run, right?

In the second case, the lambda expression is the run method of the Runnable, so new LongRunningTask() will be run. Note that this does not call the run method of LongRunningMethod (the code that you want executed). This just calls the constructor.

If you really want to use a lambda expression (though I don't see the point), you can do:

executorService.execute(() -> new LongRunningTask().run());

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=389012&siteId=1