Runnable
represents the code to be executed.
Executor
and its subclasses represent execution strategies.
This means that the former is actually consumed by the later. What you probably meant is: between simple threads and executors, which are more suitable?
The answer to this question is basically: it depends.
Executor
s are sophisticated tools, which let you choose how many concurrent tasks may be running, and tune different aspects of the execution context. They also provide facilities to monitor the tasks' executions, by returning a token (called a Future
or sometimes a promise) which let the code requesting the task execution to query for that task completion.
Threads are less elaborate (or more barebone) a solution to executing code asynchronously. You can still have them return a Future
by hand, or simply check if the thread is still running.
So maybe depending on much sophistication you require, you will pick one or the other: Executor
s for more streamlined requirements (many tasks to execute and monitor), Threads for one shot or simpler situations.