As your programs grow, it gets harder to manage all your threads, especially if you’re manually creating them as needed and joining them on an, even more, as-needed basis. However, this feels tedious and processor intensive.
Let’s ask a few vital questions regarding how the basic implementation of threading goes.
If we’re trying to save time, why do we waste so much overhead recreating threads? Wouldn’t it be more efficient to “reuse” threads? How do we best control how many threads are running at any given time? Is there even a way to do that, or better yet, automate this so we don’t have to?
What we need is a way to create all the threads we’ll need early and just pool them together in an easily accessible place. That way, whenever our program wants to offload work onto the threads, it can just find this pool and toss whatever processing it needs threaded into it.
No need for worrying about how many threads to create for the task. No need to create any threads as it goes. No need to assign each thread what they’ll be working on.
Conveniently, Java has a way to do exactly this. It’s called a thread pool.
A thread pool manages a pool of worker threads that connect to a work queue of
Runnable tasks waiting to be executed.
In this thread pool, the added threads idle until given work. A Blocking Queue is used to manage this work, which takes a given
Runnable object as a task to be processed and enqueues it. The idling threads, which are all watching this queue, will process the enqueued tasks on a first come first serve basis and will sort out who gets what task amongst themselves.
Once a thread finishes its task, it simply returns to watching this Blocking Queue and processes whatever tasks get enqueued next.
In other words, you enqueue a task you want processed into a thread pool’s queue, and one of the idling threads will dequeue that task and process it. This keeps your threads busy and helps with reusability, plus it adds some much-needed constraints to your memory usage when creating and using threads.
Now, while you can create and use a custom thread pool yourself, we’re going to look at Java’s built-in ways to utilize thread pooling. It does this through something called an
Executor, which we’ll talk about next!
Move on when you’re ready!