I want to understand logic of thread pool, and below there is a simple incorrect and not full implementation of it:
class ThreadPool {
private BlockingQueue<Runnable> taskQueue;
public ThreadPool(int numberOfThreads) {
taskQueue = new LinkedBlockingQueue<Runnable>(10);
for (int i = 0; i < numberOfThreads; i++) {
new PoolThread(taskQueue).start();
}
}
public void execute(Runnable task) throws InterruptedException {
taskQueue.put(task);
}
}
class PoolThread extends Thread {
private BlockingQueue<Runnable> taskQueue;
public PoolThread(BlockingQueue<Runnable> queue) {
taskQueue = queue;
}
public void run() {
while (true) {
try {
taskQueue.take().run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
What if the number of threads to execute exceed the taskQueue size, will the calling thread be blocked?ThreadPoolExecutor - here we can see that in this case it's a work of rejected execution handler, but I still can not understand how does it work. Thanks in advance for any help.
EDIT:
set max size of blocking queue to 10
Imagine a group of bricklayers (your threads) building a wall, and a pile of bricks (your BlockingQueue).
Each bricklayer takes a brick from the pile, positions it, and then pick another one (taskQueue.take()) - until there are bricks in the pile, the bricklayers are kept busy.
A truck arrives from time to time, filling the pile with more bricks - but there is only a limited space on the pile, if there is no space the truck stops and wait until enough bricks have been used by the bricklayers.
As long there are enough bricks in the pile (more than the number of bricklayers) you can rest assured all bricklayers will have enough to work with - but when the pile start being empty the bricklayers will have to stop working until new bricks are delivered.
You have to pick a suitable number of bricklayers, to few and the truck will be often waiting for space in the pile, too many and most of them will be idle waiting for new bricks.
Implementation-wise, in general, Java gives you a threadpool, you rarely create your own -
ExecutorService threadExecutor = Executors.newFixedThreadPool( 3 );
and then you call:
threadExecutor.submit(Runnable...);
to add a task to the queue.
What if the number of threads to execute exceed the taskQueue size, will the calling thread be blocked?
The size of the queue is the number of tasks which are NOT running. Typically it will be empty even when the threads are busy. Having a queue length which matches the number of threads has no significance and nothing special happens at this point.
here we can see that in this case it's a work of rejected execution handler
The rejection handler is only called if the queue is full. Your queue has no limit so it wouldn't be called even if you supported this feature.
However, if it did have a limit and it supported this feature, the typical behaviour is to throw an exception. You can make it do other things such as block, have the current thread run the task (which is my preference) or ignore the task.
I still can not understand how does it work.
When you offer() a task to a queue, it return false if the queue could not accept it. When this happens call the rejected execution handler.
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