线程池中核心参数关系源码解读

线程池创建中核心参数关系源码解读

核心参数

  • 核心线程数(corePoolSize)

业务线程数安装CPU密集型1N,IO密集型2N,多了会抢占资源 (Nlinux服务CPU核大小)

  • 最大线程数(maximumPoolSize)

业务线程数安装CPU密集型1N,IO密集型2N,多了会抢占资源 (Nlinux服务CPU核大小)

  • 空闲线程的保活时间(keepAliveTime)

多出的核心线程的空闲线程存活时间

  • 任务队列(workQueue)

BlockingQueue 接口的某个实现(常使用 ArrayBlockingQueue 和 LinkedBlockingQueue)

  • 拒绝策略defaultHandler

默认:丢弃任务并抛出RejectedExecutionException异常,
RejectedExecutionHandler defaultHandler = new AbortPolicy(),一共四种策略

参数关系源码解读

ThreadPoolExecutor#execute方法创建线程

    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));


    private final BlockingQueue<Runnable> workQueue;

    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.
         上面的英文翻译
         * 1。如果运行的线程少于corePoolSize,请尝试以给定的命令作为第一个线程启动一个新线程任务。对addWorker的调用会自动检查runState和        
         * workerCount,因此可以防止添加的假警报线程当它不应该,通过返回false。     
         * 2。如果一个任务可以成功地排队,那么我们仍然需要再次检查是否应该添加线程(因为上次检查后现有的已经死了)或那样进入该方法后,池关闭。所以我们         
         *重新检查状态,并在必要时回滚登记停止,如果没有,则启动一个新线程。
         * 3。如果我们不能对任务进行排队,那么我们尝试添加一个新的线程。如果它失败了,我们知道我们被关闭或饱和因此,拒绝这个任务。
         */
        int c = ctl.get();
        //1:如果目前运行的线程小于核心线程, addWorker创建线程,true同时把改创建的线程标记为核心线程
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        //2: isRunning(c)当前的线程是否都在运行 ,新来线程添加阻塞队列中
        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);
        }
        //3:如果阻塞队列已满,则再创建线程,同时把改创建的线程标记为非核心线程
        else if (!addWorker(command, false))
       //4:如果不能再创建线程,则把新加入的线程添加到拒绝策略中     目前运行的线程大于(核心线程数+阻塞队列数)则不能创建
            reject(command);
    }

四创建线程池类

  • 四类程序:newFixedThreadPool newSingleThreadExecutor newCachedThreadPool newScheduledThreadPool

注意:1:newFixedThreadPool (坑1:LinkedBlockingQueue的队列默认值数很大,会导致OOM) 2:newCachedThreadPool (坑1:线程数默认值,会导致OOM)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值