线程池的底层原理
作者:bin线程池的创建实际上都是同一个方法(ThreadPoolExecutor):
我们看他的变量:
corePoolSize : 核心线程数,即队列未满时,线程跑的数量
maximumPoolSize:最大线程数,即如果队列满了,可以将最大线程数加到多少
workQueue : 新建的线程等待队列
keepAliveTime : 线程的存活时间,即线程跑完任务后,多久被回收掉
threadFactory:线程工厂,用于创建线程
handler:队列满且达到最大核心线程数时,执行的拒绝策略
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
线程池的状态:
    //接受新任务并处理排队的任务
    private static final int RUNNING    = -1 << COUNT_BITS;
    //不接受新任务,但是处理排队的任务
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    //不接受新任务,不处理排队任务和中断进行中的任务
    private static final int STOP       =  1 << COUNT_BITS;
    //所有任务都被终止了,workerCount为0,为此状态时还将调用terminated()方法
    private static final int TIDYING    =  2 << COUNT_BITS;
    //terminated()已执行完成
    private static final int TERMINATED =  3 << COUNT_BITS;
3种不同的队列:
SynchronousQueue(直接提交策略)
不会用队列取缓存任务,运行中的线程达到maximumPoolSize时,就无法新增任务,执行异常策略。
private static ExecutorService cachedThreadPool = new ThreadPoolExecutor( 4, 10, 0, TimeUnit.MILLISECONDS, new SynchronousQueue<>(), r -> new Thread(r, "ThreadTest"));
LinkedBlockingQueue(无界队列):达到maximumPoolSize时,就加入队列,因为是链表,会一直加,直到OOM,插入和拉取分别2个锁,因此linked读写效率会比array更高
private static ExecutorService cachedThreadPool = new ThreadPoolExecutor( 4, Runtime.getRuntime().availableProcessors() * 2, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(Integer.MAX_VALUE), r -> new Thread(r, "ThreadTest") );
ArrayBlockingQueue(有界限队列):运行线程数达到corePoolSize时,加入队列,队列达到最大时,添加新线程,插入和拉取使用相同但锁,达到maximumPoolSize时,采取拒绝策略
是数组有界,LinkedBlockingQueue是链表无界,但link要注意不要内存溢出。
private static ExecutorService cachedThreadPool = new ThreadPoolExecutor( 4, Runtime.getRuntime().availableProcessors() * 2, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(32), r -> new Thread(r, "ThreadTest"));