线程池的执行流程

1.概述:由于我们自己每次创建线程都会消耗一定的资源,并且当线程执行结束后就会被回收,这样反复地创建线程就会消耗非常大的系统资源。我们可以使用线程池来管理和维护一组线程,当核心线程执行完线程任务后不会被回收,成为空闲线程,当有新的线程任务提交进来,空闲线程会优先分配给线程任务,可以减少线程的创建。

2.线程池的配置参数

在创建线程池对象时,我们需要传进一些关于线程池的配置参数,主要为以下几种:

核心线程数(corePoolSize):该线程池中核心线程的数量,核心线程执行完线程任务后不会被回收

最大线程数(maximumPoolSize):该线程池中最多可以创建的线程数,超出核心线程数所创建的线程称为非核心线程,非核心线程执行完线程任务后超过设置的存活时间后会被回收

非核心线程的存活时间(keepAliveTime):非核心线程执行完线程任务后,存活超过该时间被回收。

工作队列(workQueue):当线程池中没有空闲线程且达到核心线程数时,会将新提交的线程任务放入工作队列中。

线程工厂对象(threadFactory):用于创建线程并设置线程名。

拒绝策略对象(handler):当工作队列满后并且达到最大线程数,会执行拒绝策略。

因为每个线程池类都是ThreadPoolExecutor类或及其子类,所以可以通过创建ThreadPoolExecutor类对象来创建线程池。

public static void main(String[] args) {
		//创建线程池,设置配置参数
		ThreadPoolExecutor pool=new ThreadPoolExecutor(5,10,10,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>());
		
		//向线程池提交10个线程任务
		for(int i=0;i<10;i++) {
			pool.execute(new Runnable() {
				@Override
				public void run() {
					System.out.println(Thread.currentThread().getName()+"开始执行....");
					System.out.println(Thread.currentThread().getName()+"结束执行....");
				}
			});
		}
	}

从代码中可以看出,线程池核心线程数为5,最大线程数为10,非核心线程的存活时间为10秒。

运行结果:  

从运行结果中看到,虽然我们提交了10个线程任务并设置了最大线程数为10,但在运行结果中只有5个线程在重复执行。接下来,就让我们学习一下线程池的执行流程。

3.线程池的执行流程

以上的流程图为线程池的大致执行流程:

(1)当新的线程任务提交到线程池后,线程池会判断当前线程池中是否有空闲的线程,如果有,就将空闲线程分配给线程任务执行。

(2)如果没有空闲线程,线程池就会判断当前线程池中的线程数是否达到核心线程数,如果没有达到核心线程数,就会创建出一个新的线程用于执行线程任务,该线程执行完任务后不会被回收。否则,线程池就会判断工作队列是否已满

(3)如果工作队列没满,就将提交的线程任务放入到工作队列中等待执行,否则,线程池就会去判断当前线程池中的线程数是否达到最大线程数

(4)如果达到最大线程数,就会执行拒绝策略,否则,线程池就会新创建出一个线程对象去执行线程任务,与第(2)步不同的是,这次新创建的线程为非核心线程,该线程执行完线程任务后,如果存活时间超出该线程池的非核心线程存活时间就会被回收

 以上面的案例代码来看,当我们提交第一个线程任务时,线程池中还没有线程,所以会创建出一个核心线程来执行该线程任务,随后的第二到五个线程任务都会创建出一个核心线程,此时线程池中的线程数已达到核心线程数,当后面的线程任务提交进来后,由于我们使用的LinkedBlockingQueue无界(实际上容量由硬件决定)队列没满,所以后面提交的5个线程任务都会放入工作队列当中。当正在执行的每一个线程任务执行完后,就会空闲出一个线程,然后由空闲线程执行工作队列中的线程任务,直到工作队列为空。这就是为什么我们在上面的运行结果中只看到了5个线程的原因。

4.线程池的状态

线程池可以分为以下5种状态:

RUNNING状态:当向线程池提交任务时,线程池就处于运行状态。

SHUTDOWN状态:在RUNNING状态下,调用shutdown()方法使线程池进入SHUTDOWN状态,该状态会等到线程任务执行完后,进入TIDYING状态。

STOP状态:在RUNNING状态下,调用shutdownNow()方法使线程池进入STOP状态,该状态会中断当前正在执行的线程任务并将未执行完的线程任务返回,然后进入TIDYING状态。

TIDYING状态:整理状态,表明所有的线程任务都已执行结束。自动调用terminated()方法,然后进入TERMINATED状态。

TERMINATED状态:表示该线程池彻底关闭。

 通过线程池可以更好地管理和维护多个线程,减少了线程的创建,提高了每个线程的复用性。 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值