Apart from the fact that the Executor
interface has some advantages over plain threads (management, for example), is there any real internal difference (big performance difference, resource consumption...) between doing:
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(runnable);
And:
Thread thread = new Thread(runnable);
thread.start();
I'm only asking about a single thread here.
Executors#newSingleThreadExecutor() creates ThreadPoolExecutor object under the hood,
see the code here: http://www.docjar.com/html/api/java/util/concurrent/Executors.java.html
The documentation of ThreadPoolExecutor explains in what situations it gives advantages:
If all you need is to just run single thread only once in a while (say once an hour), then in terms of performance, using
ThreadPoolExecutor
may be slower, since you need to instantiate the whole machinery (pool + thread), then throw it away from memory.But if you want to use this single thread often (say every 15 seconds), then the advantage is that you create the pool and thread only once, keeping it in memory, and use it all the time saving time creating a new thread every now and then (which might be quite expensive, if you want to use it say every 15 seconds or so).
If you only get one
Runnable
to execute, then there is no big difference between them.Using plain thread may be a little more efficient because creating an
ExecutorService
such asThreadPoolExecutor
has something to do besides creating a new thread. For example, creating blocking queue, creating policy, though these things are done implicitly.And you have to
shutdown
the executor after this runnable has been executed. Otherwise the single thread in this pool will never exit.It is an abstraction and those always come at "cost":
The major difference is that the service enables you to submit multiple tasks, whereas the thread can run exactly one Runnable. On the other hand, you have to worry about things such as "shutting down" the service.
A rule of thumb: performance aspects should be close to "ignorable" here. Because of that, you prefer the "more abstract" executor service solution. Because that allows you to separate your concerns from the actual threading. And more importantly: if you ever choose to use a different kind of implementation for that service ... the rest of your code should not need to care about that.
Long story short: abstractions cost, but in this case, you typically prefer the "more abstract" solution. Because in the end, that reduces the complexity of your solution.
The major difference is in task execution policy.
By creating a
Thread
instance or subclassingThread
you are basically executing a single task.Using
Executors.newSingleThreadExecutor()
on the other hand allows you to submit multiple tasks. Since those tasks are guaranteed not to be executed concurrently, this allows you to exploit the following thread confinement benefits: