Can I use Callable threads without ExecutorService? We can use instances of Runnable and subclasses of Thread without ExecutorService and this code works normally. But this code
While interfaces are often created with an intended use case, they are never restricted to be used in that way.
Given a Runnable you can submit it to an ExecutorService, or pass it to the constructor of Thread or you can invoke its run() method directly like you can invoke any interface method without multi-threading involved. And there are more use cases, e.g. AWT EventQueue.invokeLater(Runnable) so never expect the list to be complete.
Given a Callable, you have the same options, so it’s important to emphasize that, unlike your question suggests, invoking call() directly does not involve any multi-threading. It just executes the method like any other ordinary method invocation.
Since there is no constructor Thread(Callable) using a Callable with a Thread without an ExecutorService requires slightly more code:
FutureTask futureTask = new FutureTask<>(callable);
Thread t=new Thread(futureTask);
t.start();
// …
ResultType result = futureTask.get(); // will wait for the async completion