Executor corepoolsizeize为零,具有有限的LinkedBlockingQueue

时间:2014-01-05 15:06:24

标签: java multithreading executorservice

我在实践中经历了Java Concurrency,并在8.3.1 Thread Creation and Teardown中找到了一个声明。下面是声明 - “即使没有要执行的任务,实现也会尝试将池维持在此大小,并且除非工作队列已满,否则不会创建比此更多的线程。”为了验证相同,我写了一个小代码

package com.executor;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class MyJobSubmitterThread extends Thread {

    public static ExecutorService objExecutorService = new ThreadPoolExecutor(0, 1, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(2));

    public static int counter = 1;
    @Override
    public void run() {
        //Using Runnable
        while(!objExecutorService.isShutdown()){
            try{
            objExecutorService.execute(new RandomNumberGenerator());
            if(counter > 10){
                objExecutorService.shutdownNow();
                if(objExecutorService.isTerminated()){
                    System.out.println("Runnable - Terminated");
                }
                //objExecutorService.execute(new RandomNumberGenerator());
            }
            int objBlockingQueueSize = ((ThreadPoolExecutor)objExecutorService).getQueue().size();
            ++counter;
            }catch (RejectedExecutionException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }

    }
}

故意不要将RandomNumberGenerator类的代码放在此问题的上下文中。

根据上面引用的语句,除非第三个任务被提交到队列,否则不应该创建和启动线程,但是与之相反,线程被创建并启动。当线程在10秒后死亡保持活着的时间,它刚刚在提交作业时创建。当我查看Java 1.7源代码中的execute方法代码时,它就像

else if (workerCountOf(recheck) == 0)
            addWorker(null, false);

有人可以解释为什么代码的行为与JCIP书中的陈述不同,反之亦然?我在这里错过了一点吗?

2 个答案:

答案 0 :(得分:2)

本书中的陈述是准确的,但需要注意的是ThreadPoolExecutor确保在有工作要做的时候至少有1个线程正在运行(即corePoolSize == 0是特殊情况)。

答案 1 :(得分:0)

您将核心池大小设置为0,将最大池大小设置为1.这意味着它最多只有一个线程来执行任务。并且由于线程数大于核心池大小(1> 0),因此该线程在保持空闲以保持活动时间之后将被移除。所以我认为情况正常。

ThreadPoolExecutor 尝试保持线程数等于核心池大小,如果线程数大于核心池大小则删除空闲线程并每次创建新线程,直到达到核心池大小。