线程池的执行流程

要了解线程池的执行流程,我们首先就要知道什么是线程池?

线程池就是里面含有若干线程的容器,没有任务时,线程池里面的这些线程都处于等待空闲状态。如果有新的线程任务,就分配一个空闲线程执行任务。如果所有的线程都处于忙碌状态,线程池就会创建一个新的线程,亦或者是将任务放到工作队列中等待。

一、线程池的执行流程 

线程池的执行流程_第1张图片

线程池的执行流程基本是:核心线程、工作队列、非核心线程、拒绝策略

  1. 当出现一个新的线程任务时,线程池会先在线程池中分配一个空闲线程,来执行这个任务

  2. 如果出现新任务时线程池中没有空闲线程,这时线程池就会判断当前“存活线程数”是否小于核心线程数corePoolSize

    1.  “存活线程数” < corePoolSize:   线程池就会创建一个新的线程,用来处理新任务

    2. “存活线程数”  = corePoolSize:   这时线程池就要判断工作队列了(队列中存储的就是等待执行的线程)

      1.   工作队列未满(即还有位置可以存放任务):就将该线程放入工作队列中进行等待,等线程池中出现空闲线程,就按照“先进先出”的规则分配执行
      2. 工作队列已经满了:判断当前存活线程数是否已经达到最大线程数
        1.    “存活线程数”  <  “最大线程数”:创建一个新线程执行新任务
        2.    “存活线程数”  >   “最大线程数”:直接采用拒绝策略

二、线程池的操作与使用

Java中提供了三种类或接口来使用线程池,分别是:

1、ExecutorService接口:进行线程池的操作访问

2、Executors类:创建线程池的工具类

3、ThreadPoolExecutor及其子类:封装线程池的核心参数和运行机制

//线程池基本使用方式
//创建一个ThreadPoolExecutor类型的对象,代表固定大小的线程池
ExecutorService executorService=Executors.newFixedThreadPool(4);//该线程拥有四个线程


//执行任务
executorService.execute(task1);
executorService.execute(task2);
executorService.execute(task3);
executorService.execute(task4);
executorService.execute(task5);

//使用结束后关闭线程
executorService.shutdown();

线程池的创建有四个参数分别是:

corePoolsize线程池核心线程数 

maximumPoolSize线程池最大线程数

keepAliveTime非核心线程存活时间

BlockingQueue阻塞工作队列

三、执行线程任务

execute():只能提交Runnable类型的任务,没有返回值;当任务出现异常时通常直接抛出

submit():既能提交Runnable类型任务也能提交Callable类型任务,可以返回Future类型结果,用于获取线程任务执行结果;当任务产生异常时通常捕获异常

public class Pool {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
//		计算1-100w的之间所有数字的累加和,每10w个数字交给1个线程处理
//		创建一个固定大小的线程池
		ExecutorService executorService=Executors.newFixedThreadPool(4);
		
//		创建集合,用于保存Future执行结果
		List> futureList=new ArrayList>();
		
//		每10w个数字,封装成一个Callable线程任务,并提交给线程池
		for(int i=0;i<=900000;i+=100000) {
			Future result=executorService.submit(new CalcTask(i+1, i+100000));
			futureList.add(result);
		}
		
		int result=0;
		for(int i=0;i{
	private int begin,end;
	
	
	public CalcTask(int begin, int end) {
		super();
		this.begin = begin;
		this.end = end;
	}


	@Override
	public Integer call() throws Exception {
		int result=0;
		for(int i=begin;i<=end;i++) {
			result+=i;
		}
		System.out.printf("线程%s计算%d-%d范围的任务结束!\n",Thread.currentThread().getName(),begin,end);
		
		return result;
	}
	
}

四、关闭线程池

关闭线程池有两种方法:

  1. shutdown()方法:此方法在当前任务执行完毕后关闭线程池
  2. shutdownNow()方法:此方法会离开执行关闭线程池操作,无论当前正在执行的任务有没有执行完

awaitTermination()方法:可以检查线程池是否关闭 

五、线程池的状态

线程池的状态可分为: RUNNING,  SHUTDOWN,    STOP,   TIDYING ,  TERMINATED

RUNNING:运行状态:线程池一旦被创建就处于RUNNING状态

 SHUTDOWN :关闭状态:该状态线程池不会接收新任务,但会处理工作队列中的任务

STOP:停止状态:该状态不会接收新任务,也不会处理阻塞队列中的任务,而且会中断正在运行的任务

TIDYING:整理状态:所有任务已运行终止

TERMINATED:终止状态:该线程池彻底关闭

线程池的执行流程_第2张图片

 

 

 

你可能感兴趣的:(java,开发语言)