I'm using java.util.concurrent
's Executors
class to create a fixed thread pool for running request handlers for a web server:
static ExecutorService newFixedThreadPool(int nThreads)
and the description is:
Creates a thread pool that reuses a fixed set of threads operating off a shared unbounded queue.
However, I am looking for thread pool implementation which will do the exact same thing, except with a bounded queue. Is there such an implementation? Or do I need to implement my own wrapper for the fixed thread pool?
Bounded thread pools allow the programmer to specify an upper limit on the number of threads that can concurrently execute in a thread pool. Programs must not use threads from a bounded thread pool to execute tasks that depend on the completion of other tasks in the pool.
By default, the MaxThreads of the ThreadPool is very high. Usually you'll never get there, your app will crash first. So when all threads are busy the new tasks are queued and slowly, at most 1 per 500 ms, the TP will allocate new threads.
In computer programming, a thread pool is a software design pattern for achieving concurrency of execution in a computer program. Often also called a replicated workers or worker-crew model, a thread pool maintains multiple threads waiting for tasks to be allocated for concurrent execution by the supervising program.
ThreadPoolExecutor is an ExecutorService to execute each submitted task using one of possibly several pooled threads, normally configured using Executors factory methods. It also provides various utility methods to check current threads statistics and control them.
What you want to do is new your own ExecutorService, probably using ThreadPoolExecutor. ThreadPoolExecutor has a constructor which takes a BlockingQueue and to get a bounded queue you use for example ArrayBlockingQueue properly constructed for bounding. You can also include a RejectedExecutionHandler in order to determine what to do when your queue is full, or hang on to a reference to the blocking queue and use the offer methods.
Here's a mini example:
BlockingQueue<Runnable> linkedBlockingDeque = new LinkedBlockingDeque<Runnable>( 100); ExecutorService executorService = new ThreadPoolExecutor(1, 10, 30, TimeUnit.SECONDS, linkedBlockingDeque, new ThreadPoolExecutor.CallerRunsPolicy());
I've solved this with a Semaphore which I use to throttle tasks being submitted to the ExecutorService
.
Eg:
int threadCount = 10; ExecutorService consumerPool = Executors.newFixedThreadPool(threadCount); // set the permit count greater than thread count so that we // build up a limited buffer of waiting consumers Semaphore semaphore = new Semaphore(threadCount * 100); for (int i = 0; i < 1000000; ++i) { semaphore.acquire(); // this might block waiting for a permit Runnable consumer = () -> { try { doSomeWork(i); } finally { semaphore.release(); // release a permit } }; consumerPool.submit(consumer); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With