「后端开发」系列——Java线程池

本文详细探讨了Java线程池的工作原理,包括任务提交、核心线程池、阻塞队列和最大线程池的管理。讨论了如何通过execute和submit提交任务,核心线程池是否预先创建线程,以及任务何时从阻塞队列获取。此外,解释了阻塞队列存在的必要性,以避免过度创建线程导致系统资源浪费。
摘要由CSDN通过智能技术生成

Java线程池

 线程池是用来管理线程生命周期的一个对象池,通过使用线程池,可以让开发人员不过于关注线程的创建、销毁等过程。并且通过使用线程池,合理的设置核心线程数,最大线程池等参数,可以提高系统的性能,避免出现一些例如OOM的问题。
线程池执行过程

以上就是主线程中提交任务后的执行顺序。
首先看核心线程池是否已满,如果已经满了,就把任务放入到阻塞队列中,否则就创建新的线程,执行任务。
然后看阻塞队列是否已满,如果未满,就将任务放入阻塞队列,如果已满,就放入到最大线程池中。
再看最大线程池是否已满,如果已满就执行拒绝策略。未满就在最大线程池中创建线程执行任务。

在这个任务提交过程中深入考虑可能会遇到这几个问题。

  • 主线程是通过execute来提交任务的吗?还有其他方式吗?
  • 核心线程池中有存放线程对象吗?还是每次有任务到核心线程池的时候,再去创建线程?
  • 任务放入到阻塞队列之后,线程池是在什么时机去获取的任务?
  • 任务流转到了最大线程池这里,最大线程池会自己创建线程执行任务?如果这样,中间为什么要有一个阻塞队列的步骤?

下面我们就一一看一下这几个问题。

1. 主线程是通过execute来提交任务的吗?还有其他方式吗?

线程池可以通过execute,submit来提交任务。
但是最终都是通过调用execute来执行提交任务。

  • 当核心线程数还未达到corePoolSize的时候,会尝试新建一个线程来执行这个任务。调用addWorker方法会自动检查运行状态和工作者数量,确保任务交给新线程出错时会有异常返回。
  • 如果一个任务可以正常排队等待被执行,我们依旧需要二次检查我们是否可以新建一个线程(因为存在的一个线程可能在最后一次检查之后死掉了)或者线程池是否在进入这个方法之前已经关掉了。所以我们需要再一次检查在任务入队停止的时候是否需要回滚,或者新建一个线程。
  • 如果任务不能排队,我们试图创建一个新的线程,如果这也失败了,我们要知道线程池可能被关掉了,或者线程池饱和了,这个时候就需要执行拒绝策略。
    //接口的实现
    public void execute(Runnable command) {
   
        if (command == null)
            throw new NullPointerException();
        /*
         * 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 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值