3
public class myService {

    @Autowired
    ExecutorService executor;

    public Result getServiceResult(Token token, Profile profile){
        //validate token and profile
        return getResult(token, profile).get();
    }

    private getResult (Token token, Profile profile){
       Future<Result> = threadPoolExecutor.submit(
               () -> myManager.createAccount(token, profile));
    }
}

This code runs fine at my current work. I am not able to able to understand how threadPoolExecutor.submit is passed a "Function/Method" but not a callable?

I am using Java 8 and Spring framework.

Edd
  • 3,724
  • 3
  • 26
  • 33
brain storm
  • 30,124
  • 69
  • 225
  • 393
  • 2
    Why do you thing a Function is passed? – JB Nizet May 26 '15 at 19:39
  • @JBNizet: can you elaborate? – brain storm May 26 '15 at 20:34
  • 1
    What makes you think the code you posted passes a Function to submit()? Given http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html, what makes you think submit() accepts a Function? Given that there is only one documented submit() method returning a `Future` in ExecutorService, what do you think the type of `() -> myManager.createAccount(token, profile)` is? – JB Nizet May 26 '15 at 20:42
  • @JBNizet: `mymanager.createAccount` takes two arguments `token` and `profile` and returns object of type `result`. Since Java 8, supports passing function, I thought we are passing function. But I am not clear now what is being passed? can you help? – brain storm May 26 '15 at 20:53
  • 2
    What is passed is an instanceof Callable. This Callable instance is written as a lambda expression. Explaining how lambdas work would be much too broad here. Read https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html, and google for the bazillions of articles about Java 8 lambdas and functional interfaces. A Function and a lambda expression are not the same thing. Function is a new (functional) interface in Java 8. But any functional interface instance, not just Function, can be expressed as a lambda expression. – JB Nizet May 26 '15 at 20:57

1 Answers1

6

As I understand it, you want to know why you seem to be able to pass a "Function" to the ThreadPoolExecutor.submit() method that takes a Callable, not a Function.

The explanation is that the method can't take a Function as a parameter; what you're seeing is a Callable being passed in, expressed as a lambda expression (Essentially an expression that uses the right arrow (->) syntax).

As outlined in the previous document, a lambda expression is used to provide an implementation of an interface that has exactly one abstract method that is not an override of a method on Object. These are typically annotated FunctionalInterface, which is possibly where your confusion arose, although this is not a requirement as outlined in the Language Specification:

A functional interface is an interface that has just one abstract method (aside from the methods of Object), and thus represents a single function contract. This "single" method may take the form of multiple abstract methods with override-equivalent signatures inherited from superinterfaces; in this case, the inherited methods logically represent a single method.

In your example above, depending on the return type of myManager.createAccount(), you're either providing an implementation of Callable (if you return anything), or Runnable if it's a void method:

() -> myManager.createAccount(token, profile)

Your lambda matches the method signature of the abstract call() or run() methods because it takes no parameters (As indicated by the () on the left hand side of the arrow), and returns void or some result.

Edd
  • 3,724
  • 3
  • 26
  • 33
  • I was reading about `functionalInterface` annotion. It is this which makes it possible to pass lambda. But you mention that `functionalInterface` annotion is not a requirement. why is it so? – brain storm May 27 '15 at 16:41
  • @brainstorm I've added the relevant section of the JLS outlining what a Functional Interface actually is, but if you look at the JavaDoc for the FunctionalInterface annotation (linked above) it states it's not required and is just a convenience. – Edd May 27 '15 at 16:54