Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple ThreadPool implementation

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

like image 421
pvllnspk Avatar asked Jan 15 '23 03:01

pvllnspk


2 Answers

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.

like image 67
thedayofcondor Avatar answered Jan 17 '23 17:01

thedayofcondor


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.

like image 24
Peter Lawrey Avatar answered Jan 17 '23 17:01

Peter Lawrey