线程池中的核心参数
int corePoolSize:核心线程数,即使线程池中无任务执行,也会创建该数量的线程。
int maximumPoolSize:最大线程数,当核心线程数不够,且队列已满的情况下,会另外创建线程执行任务。
long keepAliveTime:当线程池中的线程处于空闲状态,超过KeepAliveTime时间,则销毁该线程,保持运行的线程数=核心线程数。
BlockingQueue workQueue:任务队列,当任务大于核心线程数,任务会加到队列中等待执行
RejectedExecutionHandler defaultHandler:拒绝策略,详情参考
线程池中四种拒绝策略

下面是线程池的使用以及验证参数
设置核心线程数2,最大线程数7,空闲时存活时间8秒,队列容量3,设置10个线程任务,放入线程池中,为了造成线程数堆积,让任务睡眠5秒。当核心线程数有任务执行,则将新任务加入队列,当任务队列满了,则扩大线程至最大线程数。

public class ThreadPool {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<>(3);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor
                (2, 7, 8, TimeUnit.SECONDS, blockingQueue, new ThreadPoolExecutor.DiscardPolicy());
        for(int i = 0; i < 10; i++) {
            threadPoolExecutor.execute(
                    new Thread(){
                        @Override
                        public void run() {
                            try{
                                System.out.println(Thread.currentThread().getName()+" start");
                                //体现线程数满的场景,让任务在此处停留,造成线程堆积
                                Thread.sleep(5000);
                                System.out.println(Thread.currentThread().getName() + " end");
                            }catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
            );
        }
        //验证KeepAlive,当空闲线程超过KeepAliveTime=8秒,则将线程数降低至核心线程
        Thread.sleep(30000);
        System.out.println("休息了30s...");
        for(int i = 0; i < 5; i++) {
            threadPoolExecutor.execute(
                    new Thread(){
                        @Override
                        public void run() {
                            try{
                                System.out.println(Thread.currentThread().getName()+" start");
                                Thread.sleep(3000);
                                System.out.println(Thread.currentThread().getName() + " end");
                            }catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
            );
        }
    }
}

执行结果,可以发现起了7个线程执行任务,因为堆积的任务数超过核心数+队列容量,则扩大至最大线程数7。中间休息的30秒,为了验证空闲时线程数是否会降低至核心线程数,观察运行结果,可以发现保留了两个线程数执行任务。

pool-1-thread-1 start
pool-1-thread-2 start
pool-1-thread-3 start
pool-1-thread-4 start
pool-1-thread-5 start
pool-1-thread-6 start
pool-1-thread-7 start
pool-1-thread-2 end
pool-1-thread-3 end
pool-1-thread-2 start
pool-1-thread-1 end
pool-1-thread-3 start
pool-1-thread-1 start
pool-1-thread-6 end
pool-1-thread-4 end
pool-1-thread-7 end
pool-1-thread-5 end
pool-1-thread-2 end
pool-1-thread-1 end
pool-1-thread-3 end
休息了30s...
pool-1-thread-3 start
pool-1-thread-1 start
pool-1-thread-1 end
pool-1-thread-1 start
pool-1-thread-3 end
pool-1-thread-3 start
pool-1-thread-3 end
pool-1-thread-3 start
pool-1-thread-1 end
pool-1-thread-3 end

部分源码:

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         * Proceed in 3 steps:
         *
         * 1. If fewer than corePoolSize threads are running, try to
         * start a new thread with the given command as its first
         * task.  The call to addWorker atomically checks runState and
         * workerCount, and so prevents false alarms that would add
         * threads when it shouldn't, by returning false.
         *
         * 2. If a task can be successfully queued, then we still need
         * to double-check whether we should have added a thread
         * (because existing ones died since last checking) or that
         * the pool shut down since entry into this method. So we
         * recheck state and if necessary roll back the enqueuing if
         * stopped, or start a new thread if there are none.
         *
         * 3. If we cannot queue task, then we try to add a new
         * thread.  If it fails, we know we are shut down or saturated
         * and so reject the task.
         */
        int c = ctl.get();
        //运行的线程数小于核心线程数,则加入任务线程,
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        //如果加入队列成功,进行两次检查能否加入
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //执行到此处,说明核心线程数和队列都满了,则需创建新线程执行,
        //如果创建新线程失败,则执行拒绝策略
        else if (!addWorker(command, false))
            reject(command);
    }