ExecutorService is an interface in the JDK. An implementation of the interface can execute a Runnable or Callable class in an asynchronous way. The interface only defines the API for the implementation and does not require that the invocation is asynchronous. In reality, that is why we use such a service. Invoking the run method of a Runnable interface in a synchronous way is simply calling a method. We do not need a special class for that.
The Runnable interface defines one run method. It has no arguments, returns no value, and does not throw an exception. The Callable interface is parameterized and the only method it defines, call, has no argument, but returns a generic value and may also throw Exception. In a code, we implement Runnable if we just want to run something, and Callable when we want to return something. Both of these interfaces are functional interfaces...