0
votes

I have a example code.

@Test
    public void testWithBlockQueue() throws InterruptedException {
        String poolFormat = "ServiceTaskPool-%d";
        int coreSize = 3;
        int maxSize = 3;
        int queueSize = 1;
        int idleThreadLiveInSecond = 35;

        ThreadFactory factory = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r);
            }
        };
        ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(queueSize);
        final ThreadPoolExecutor service = new ThreadPoolExecutor(coreSize, maxSize, idleThreadLiveInSecond,
                TimeUnit.SECONDS, queue, factory, new ThreadPoolExecutor.AbortPolicy());
        service.allowCoreThreadTimeOut(true);
        passTask(coreSize, service);
        Thread.sleep(5000);
        passTask(coreSize, service);
        System.out.printf("Thread pool state %s", service);
        Thread.sleep(6000);
    }

    protected void passTask(int coreSize, ThreadPoolExecutor service) {
        for (int i=0; i < coreSize; i++) {
            service.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.printf("Simple printf from %s \n", Thread.currentThread().getName());
                }
            });
        }
    }

When I set queueSize 2, I got exception because threadpoolexecutor can not insert one task to queue, when I set queueSize 3 is ok. I don't understant why when I set maxSize = 4, test is ok. It's from documentation.

  1. If the number of threads is less than the corePoolSize, create a new Thread to run a new task.
  2. If the number of threads is equal (or greater than) the corePoolSize, put the task into the queue.
  3. If the queue is full, and the number of threads is less than the maxPoolSize, create a new thread to run tasks in.
  4. If the queue is full, and the number of threads is greater than or equal to maxPoolSize, reject the task.
1

1 Answers

0
votes

In fact, when maxSize = 4, there could be exception thrown

First time call passTask(coreSize, service), we get task1, task2, task3. And thread1, thread2, thread3 will be created to run them.

Second time call passTask(coreSize, service):

  1. i = 0, we get task4, and task4 will be put in the queue.
  2. i = 1, we get task5.

    2.1. If task4 is still in the queue, then thread4 will be created and run task5;

    2.2. If task4 has been taken from queue by thread1 or thread2 or thread3, task5 will be put in the queue.

  3. i = 2, whe get task6.

    3.1. If task4 is still in the queue, there must be 4 alive threads, and because queue is full, exception will be thrown;

    3.2. If task5 is in the queue, there must be three threads alive, so thread4 will be created and run task6;

    3.3. If the queue is empty, task6 will be put in the queue.

On condition 3.1, exception could be thrown. But in tests, the task will be taken from the block queue very fast, so this counld hardly happen.

P.S.:

When maxSize = 3 and queueSize = 1, add this line

Thread.sleep(10);

after

for (int i=0; i < coreSize; i++) {

can make your code run with no Exception.