【Java】の基础——线程池

一、重要的成员变量

corePoolSize:核心线程池大小
maximumPoolSize:线程池最大线程数
keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止
workQueue:一个阻塞队列,用来存储等待执行的任务
runState:表示线程池的当前状态

继承关系

这里写图片描述

二、线程池状态

volatile int runState;
static final int RUNNING    = 0;
static final int SHUTDOWN   = 1;
static final int STOP       = 2;
static final int TERMINATED = 3;
  • 当创建线程池后,初始时,线程池处于RUNNING状态;

  • 调用了shutdown()方法,则线程池处于SHUTDOWN状态,此时线程池不能够接受新的任务,它会等待所有任务执行完毕;

  • 调用了shutdownNow()方法,则线程池处于STOP状态,此时线程池不能接受新的任务,并且会去尝试终止正在执行的任务;

  • 当线程池处于SHUTDOWN或STOP状态,并且所有工作线程已经销毁,任务缓存队列已经清空或执行结束后,线程池被设置为TERMINATED状态。

三、任务执行原理

在ThreadPoolExecutor类中,最核心的任务提交方法是execute()方法,(通过submit也可以提交任务,但是实际上submit方法里面最终调用的还是execute()方法)

execute()方法

excute()中主要有两个方法用来将任务加入线程池:
如果线程池中当前线程数小于核心池大小 addIfUnderCorePoolSize(command)
如果线程池中当前线程数达到了核心池大小并且往任务队列中添加任务失败 addIfUnderMaximumPoolSize(command)

addIfUnderCorePoolSize()方法

  1. addIfUnderCorePoolSize()方法中首先获取锁
  2. 然后判断线程池中的线程数目是否小于核心池大小
  3. 然后判断线程池的状态是否为RUNNING
  4. 然后通过addThread()方法传入任务返回线程,如果返回不为空,则启动这个线程。

addThread()方法:

  1. 首先用传入的任务创建了一个Worker对象
  2. 然后调用线程工厂threadFactory创建了一个新的线程t(用于运行Worker)
  3. 又把thread传给Worker(Worker里面也要拿到thread的引用)
    poolSize++;
  4. 返回t

Worker

  1. 实现了Runnable接口
  2. 在while循环中如果task不为空则执行任务,执行完不断通过getTask方法从任务缓存队列里面去取任务并执行。

getTask方法

  1. 先判断当前线程池状态,如果runState为STOP或者TERMINATED,则直接返回null;如果为SHUTDOWN或者RUNNING,则从任务缓存队列取任务。
  2. 如果当前线程池的线程数大于核心池大小corePoolSize或者允许为核心池中的线程设置空闲存活时间,则调用poll(time,timeUnit)来取任务,这个方法会等待一定的时间,如果取不到任务就返回null。
  3. 最后根据取到的任务是否为null以及workerCanExit()来判断Worker是否可以退出。

概括来说:

  • 如果当前线程池中的线程数目小于corePoolSize,则每来一个任务,就会创建一个线程去执行这个任务;
  • 如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去执行;若添加失败(一般来说是任务缓存队列已满),则会尝试创建新的线程去执行这个任务;
  • 如果当前线程池中的线程数目达到maximumPoolSize,则会采取任务拒绝策略进行处理;
  • 如果线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止,直至线程池中的线程数目不大于corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线程空闲时间超过keepAliveTime,线程也会被终止。
Java线程池是一种用于管理和复用线程的机制,它可以帮助我们更好地管理线程,防止线程过多导致系统资源的浪费和性能问题。线程池通过一个池子来缓存和复用线程,让线程可以被重复利用,从而减少线程的创建和销毁的开销,提高系统的性能。 在Java中,线程池是通过java.util.concurrent包下面的Executor框架来实现的。Executor框架提供了一种将任务提交与执行分离开来的机制,它将任务的提交和执行分离开来,从而使得任务的执行更加高效和灵活。 Java线程池的主要特点包括: 1. 线程复用:线程池中的线程可以被重复利用,从而减少线程的创建和销毁的开销,提高系统的性能。 2. 控制线程数量:通过控制线程池中的线程数量,可以避免线程过多导致系统资源的浪费和性能问题。 3. 线程池大小自适应:线程池的大小可以根据需要自适应调整,以适应不同的任务负载。 4. 任务队列:线程池中通常会设置一个任务队列,用于存放等待执行的任务。 5. 线程池管理:线程池通常会提供一些管理方法,用于监控线程池的状态和执行情况。 Java线程池的使用步骤如下: 1. 创建一个线程池对象。 2. 向线程池中提交任务。 3. 线程池会自动分配线程来执行任务。 4. 等待任务执行完成。 5. 关闭线程池线程池的具体实现可以通过Java提供的ThreadPoolExecutor类来完成。ThreadPoolExecutor类提供了一些构造方法和方法,可以用来设置线程池的参数和管理线程池。同时,Java还提供了一些其他类型的线程池,例如FixedThreadPool、CachedThreadPool和ScheduledThreadPool等,可以根据需要选择不同类型的线程池来处理任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值