I suggest you take a look at the Contractor and the Contractor. They add a lot of good things to make it easier to use thread pools.
...
@ Azad provided good information and links. You should also buy and read the Java Concurrency book in practice. (often abbreviated as JCiP) Note for stackoverflow of big wigs - what about some profitable Amazon link ???
The following is my brief summary on how to use and use ExecutorService with thread pools. Let's say you want 8 threads in a pool.
You can create it using the full-featured ThreadPoolExecutor constructors, for example.
ExecutorService service = new ThreadPoolExecutor(8,8, more args here...);
or you can use simpler but less customizable Executors factories, for example.
ExecutorService service = Executors.newFixedThreadPool(8);
One of the benefits you get right away is the ability to shutdown() or shutdownNow() the thread pool and check this status with isShutdown() or isTerminated() .
If you don't care about the Runnable that you want to run, or they are very well written, standalone, never interrupted or log errors properly, etc .... you can call
execute(Runnable r);
If you care about any result (say, it calculates pi or loads an image from a web page) and / or bothers you if there was an exception, you should use one of the submit methods that Future returns. This will allow you at some point in the future to check if there is an isDone() task and get the result via get() . If there was an exception, get() will throw it (wrapped in an ExecutionException). Note. Even your future does not return anything (this is a type of Void), it may be good practice to call get() (ignoring the result of void) to check for an exception.
However, this test of the Future is a bit of a problem with the chicken and the egg. The whole point of the thread pool is to send tasks without blocking. But the Future.get () and Future.isDone () blocks ask questions about which thread calls it, and what if it is not done, do you sleep () and block?
If you simultaneously send a known part of related tasks, for example, you perform a large mathematical calculation, for example, matrix multiplication, which can be performed in parallel, and there are no particular advantages for obtaining partial results, you can call invokeAll() . Then the calling thread is blocked until all tasks are completed, when you can call Future.get() for all futures.
What if tasks are more scattered or do you really want to use partial results? Use the ExecutorCompletionService that wraps the ExecutorService. At the end of the job, they are added to the queue. This makes it easier for a single thread to poll and remove events from the queue. JCiP has a great example web page application that downloads all images in parallel and displays them as soon as they become available to respond.