If you’ve written any kind of multi-threaded code with Java, you must know java.util.concurrent.Executors and java.util.concurrent.ExecutorService classes. An
ExecutorService is an abstraction around threads that can be used to schedule and track the progress of asynchronous tasks. A nice thing about it is that you can write code that uses an
ExecutorService and decide later which implementation you choose.
ExecutorServicewith a fixed
Nnumber of threads to run the tasks.
Executors.newSingleThreadExecutor()will use a single thread to run the tasks.
Executors.newCachedThreadPool()will reuse threads instead of creating a new one for each task. This is useful when you execute lots of short-lived tasks.
Java 8 adds new methods to
Executors. One is
Executors.newWorkStealingPool(). It creates a pool of “work-stealing” threads with a number of threads equals to the number of available processors on the machine. Useful for async tasks that spawn sub-tasks.
Let’s take a look at two methods that I like:
MoreExecutors.getExitingExecutorService(ThreadPoolExecutor)converts a given
ExecutorServicethat exits when the application is complete. It will tweak the
ThreadPoolExecutorto make it produce daemon threads. And it will register a ShutdownHook to wait for their completion. That’s something you don’t want to write yourself even if it’s not complicated. It’s useful if you want your application to end gracefully even if some
ExecutorServicewas created somewhere.
MoreExecutors.sameThreadExecutor()is a really nice trick to make some multi-thread code run synchronously. What it does it use the main thread, on which the tasks are scheduled, to run the tasks. A very effective way of testing multi-threaded code is to make it synchronous,
MoreExecutors.sameThreadExecutor()is your friend!