Addev
Addev

Reputation: 32243

How does maximumPoolSize of ThreadPoolExecutor works?

I'm trying to understand ThreadPoolExecutor class. I have read this answer and the Javadoc. But my experimentation doesn't match with that description:

I initialize the threadpool with an factory for tracking the ids

int tcounter = 0;
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 1, TimeUnit.MINUTES,
        new ArrayBlockingQueue<Runnable>(1000), new ThreadFactory() {

            @Override
            public Thread newThread(Runnable r) {
                return new mThread(tcounter++, r);
            }
        });

public class mThread extends Thread {
    int id;

    private mThread(int id, Runnable run) {
        super(run);
        GLog.e("created thread " + id);
        this.id = id;
    }

}

then the task:

public class mRunanble implements Runnable {
    int value = 0;

    private mRunanble(int value) {
        super();
        this.value = value;
    }

    @Override
    public void run() {
        SystemClock.sleep(3000);
        Thread t = Thread.currentThread();
        if (t instanceof mThread) {

            GLog.e("Say " + (value) + " on thread " + ((mThread) t).id);
        } 

    }

}

and assign a button the action:

executor.execute(new mRunanble(i++));

But I spam that button and the third thread is never created, so what is for the second paramether in the ThreadPoolExecutor constructor (maximumPoolSize=4). I was specting 4 threads to be created and 2 of them to be killed after 1 minute of the end of the execution

Upvotes: 10

Views: 14991

Answers (3)

Dmytro Kryvenko
Dmytro Kryvenko

Reputation: 343

To make ThreadPool create new additional thread (to extend pool size according to maximumPoolSize parameter) try to execute this simple example:

public class Main {

    public static void main(String[] args) throws InterruptedException {

        ThreadPoolExecutor tpe = new ThreadPoolExecutor(
                1, 2, 500, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1));
        System.out.println("init pool size= " + tpe.getPoolSize() + ", queue size=" + tpe.getQueue().size());

        tpe.execute(new Task("1st", 10000));
        Thread.sleep(1000);
        print(tpe, "1st");

        tpe.execute(new Task("2nd", 0));
        Thread.sleep(1000);
        print(tpe, "2nd");

        tpe.execute(new Task("3d", 2000));
        Thread.sleep(1000);
        print(tpe, "3d");

        while (tpe.getPoolSize()>1) {           
            Thread.sleep(100);
        }
        System.out.println("pool size= " + tpe.getPoolSize() + ", queue size=" + tpe.getQueue().size());
        tpe.shutdown();
    }

    private static void print(ThreadPoolExecutor tpe, String name) {
        System.out.println("After " + name + " execute -  pool size= " + tpe.getPoolSize() + ", queue=" + tpe.getQueue());
    }

    private static class Task implements Runnable {

        private final String name;
        private final long time;

        Task(String name, long time) {
            this.name = name;
            this.time = time;
        }

        @Override
        public void run() {
            System.out.println("Run " + Thread.currentThread().getName() + "-" + name);
            try {
                Thread.sleep(time);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
            System.out.println("Finish " + Thread.currentThread().getName() + "-" + name);
        }

        @Override
        public String toString() {
            return name;
        }

    }
}

You'll get the output which demonstrates impact of maximumPoolSize and keepAliveTime:

init pool size= 0, queue size=0
Run pool-1-thread-1-1st
After 1st execute -  pool size= 1, queue=[]
After 2nd execute -  pool size= 1, queue=[2nd]
Run pool-1-thread-2-3d
After 3d execute -  pool size= 2, queue=[2nd]
Finish pool-1-thread-2-3d
Run pool-1-thread-2-2nd
Finish pool-1-thread-2-2nd
pool size= 1, queue size=0
Finish pool-1-thread-1-1st

Upvotes: 1

amicngh
amicngh

Reputation: 7899

In ThreadPoolExecutor maximumPoolSize comes in picture when corePoolSize no is not sufficient to execute your tasks and if all no are ocupied by tasks then only one more tread is being created to execute task .this no can grow upto maxPoolSize.

Edit you missunderstood the maxPoolsize concept.please refer below link.

http://www.bigsoft.co.uk/blog/index.php/2009/11/27/rules-of-a-threadpoolexecutor-pool-size

Upvotes: 2

Jeffrey
Jeffrey

Reputation: 44808

From the API for ThreadPoolExecutor:

If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full.

Your queue never fills since it has a capacity of 1000. If you change the capacity to 1, you will see Threads being created.

The Executors class uses a SynchronousQueue for its newCachedThreadPool methods, so you might want to consider using it as well.

Upvotes: 7

Related Questions