1. Return value: The primary difference between Runnable and Callable is that the Runnable interface does not return a result, while the Callable interface does. Runnable's run() method has a void return type, whereas Callable's call() method has a generic return type.
2. Exception handling: Another notable difference is in exception handling. The run() method of Runnable does not throw checked exceptions, while the call() method of Callable can throw checked exceptions. This allows Callable to handle exceptions more explicitly and propagate them to the calling thread.
3. Usage with Executor framework: When working with the Executor framework in Java, Runnables can be submitted using the execute() method, while Callables can be submitted using the submit() method. The submit() method returns a Future object, which can be used to retrieve the result of the Callable task and handle any exceptions that may have occurred during its execution.
In summary, the choice between using Runnable or Callable depends on the requirements of the task. If a task needs to return a result or handle checked exceptions explicitly, Callable is the better choice. Otherwise, Runnable can be used for simpler tasks that don't require a return value or explicit exception handling.