理解线程池原理及使用线程池

本文详细介绍了线程池的工作原理,包括核心类ThreadPoolExecutor的实现,线程池如何根据核心线程数、任务队列和最大线程数决定任务执行方式。此外,还探讨了线程池的构造参数及其意义,如corePoolSize、maximumPoolSize、keepAliveTime等,并给出了线程池在实际应用中的场景和使用策略。
摘要由CSDN通过智能技术生成

说明:文章内容均为基于个人理解,如有错误,请见谅并指出,大家一同进步,多谢 ^ _ ^。

线程池原理:

通过初始创建好一定数目的线程数量,来达到持续不断地任务并行处理的效果,并因此减少不断创建和销毁线程的开销。

线程池核心实现:

线程池的核心实现就在于ThreadPoolExecutor类。

我们先看看其继承关系

public class ThreadPoolExecutor extends AbstractExecutorService

ThreadPoolExecutor继承抽象类AbstractExecutorService

public abstract class AbstractExecutorService implements ExecutorService

AbstractExecutorService继承接口ExecutorService

public interface ExecutorService extends Executor

ExecutorService接口继承Executor接口

由此可见,Executor是顶层接口,而接口中只声明了一个方法。

public interface Executor {
   
    void execute(Runnable command);
}

那我们先来看看ThreadPoolExecutor类的这个execute的实现,其功能是啥?就是执行提交到线程池的Runnable任务的。在代码中我稍作注释,然后在后边再做一个说明。

public void execute(Runnable command) {
   
// 如果提交的任务为空,抛出空指针异常
    if (command == null)
        throw new NullPointerException();
   
    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);
}

线程池执行核心

可以说,线程池执行任务的核心在这里。

首先在线程数少于我们设置的核心线程数时,new新线程(这一工作addWorker中去做)。

如果活跃线程不少于设置的核心线程数,则将任务添加到任务队列中。只是,如果添加成功,需要再次检查,线程池是否还处于Running状态(如果不为Running,就要把加入到队列中的任务移出,并reject该任务),以及检查活跃的工作者线程数是否为0了(如果为0,创建一个新线程)。

如果任务队列已满,任务没法加入等待队列,也尝试创建新线程运行该任务。

我们看看addWorker实现

private boolean addWorker(Runnable firstTask, boolean core) {
   
	// retry 这段代码在于检查当前线程池状态以及根据给予的线程池的核心线程数或者最大线程数界限来确定是否可以添加一
	// 个worker,也就是再添加一个工作线程。如果可以添加,则工作线程数计数器也做相应调整。如果能够添加一个新线程,
	
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值