Well title says it, what is the difference between Executors.newSingleThreadExecutor().execute(command)
and new Thread(command).start();
With Executor.execute
, if an Error
or RuntimeException
is thrown in the Executor
it will be swallowed silently, while the new Thread()
will print it to System.err
.
I prefer to use ExecutorService
or ThreadPoolExecutor
even for single digit threads. They offer more flexibility.
Have a look at ExecutorService
& ThreadPoolExecutor
sections in related SE questions :
java Fork/Join pool, ExecutorService and CountDownLatch
Java's Fork/Join vs ExecutorService - when to use which?
Assume that you have started with your own thread instead of ExecutorService
. In future, if there is a need for supporting multiple threads, ExecutorService
or ThreadPoolExecutor
will offer better control and flexibility for you. You can fine-tune required number of parameters in these below APIs.
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)
One noticeable difference, is when you run new Thread(someRunnable).start();
when the runnable is finished the thread will die quietly.
The Executor though will persist until you shut it down. So running Executors.newSingleThreadExecutor().execute(command)
When you think your application or the JVM may be finished the Executor may still be running in a background thread.
Behaviourally, pretty much nothing.
However, once you have an Executor
instance, you can submit multiple tasks to it, and have them executed one after another. You can't do that simply with a raw Thread
.
Executors.newSingleThreadExecutor().execute(command) will reuse previously constructed thread, it will not created new thread as in case of new Thread(). If the thread that have not been used for sixty seconds are terminated, It's a kind of pool which contains a single thread which make its equivalent newFixedThreadPool(1).
There can be many differences, but I will show you one difference which I found very important to understand:
public void sendEventSingleThreadExecutor(Event e){
Executor.singleThreadExecutor().execute(()->{//send the event here})
}
Now, even if you call sendEventSingleThreadExecutor method 10 times, it will use only a single thread to send them. It will not create a new thread every time. Which means that the events will be sent sequentially or synchronously! You can read more from here:
Now see the below example with new thread
public void sendEventThread(Event e){
Thread(//send the event here).start();
}
If you call it 10 times, it will create 10 new threads. Which means, the executions will be asynchronous! And it could be dangerous, it can create a lot of threads depending on how many times you call sendEventThread functions.
Please note that, the code are only for demonstration purpose, it might have syntax error! If you find any wrong description here, I will be happy to be corrected.
Some more information from here
newSingleThreadExecutor. A single-threaded executor creates a single worker thread to process tasks, replacing it if it dies unexpectedly. Tasks are guaranteed to be processed sequentially according to the order imposed by the task queue (FIFO, LIFO, priority order).[4]
[4] Single-threaded executors also provide sufficient internal synchronization to guarantee that any memory writes made by tasks are visible to subsequent tasks; this means that objects can be safely confined to the “task thread” even though that thread may be replaced with another from time to time.