首页 > java线程 > 线程池的底层原理

线程池的底层原理

作者: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"));

您必须 [ 登录 ] 才能发表留言!