2.ThreadPoolExecutor线程池

本文详细介绍了Java中的线程池实现ThreadPoolExecutor,包括创建线程池的4个构造函数参数、线程池工作原理、线程池大小设定以及线程池规则。示例代码展示了如何配置和使用线程池执行任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

  1. 为什么要创建线程池:
    频繁的创建线程和关闭线程会占用系统资源,增加系统负担,降低系统性能
  2. 线程池原理:
    请求保存下来(如:队列),等有可用线程时就让线程从队列里取出一个请求进行处理
  3. 线程池大小:
    一般需要根据任务的类型来配置线程池大小, 如果是CPU密集型任务,就需要尽量压榨CPU,参考值可以设为 NCPU+1。如果是IO密集型任务,参考值可以设置为2*NCPU

通过ThreadPoolExecutor来创建一个线程池

4个构造函数

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue)
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          RejectedExecutionHandler handler)
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory)
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)

参数说明

  1. corePoolSize: 核心线程数,默认情况下核心线程会一直存活,不会受存keepAliveTime限制。除非将allowCoreThreadTimeOut(true)设置为true。
  2. maximumPoolSize:线程池所能容纳的最大线程数。超过这个数的线程将被阻塞。当任务队列为没有设置大小的LinkedBlockingDeque时,这个值无效。
  3. keepAliveTime:非核心线程的闲置超时时间,超过这个时间就会被回收。
  4. unit :指定keepAliveTime的单位,如TimeUnit.SECONDS。当将allowCoreThreadTimeOut设置为true时对corePoolSize生效。
  5. workQueue :线程池中的任务队列。常用的队列有,SynchronousQueue,LinkedBlockingDeque
  6. threadFactory :线程工厂,提供创建新线程的功能。通过线程工厂可以对线程的一些属性进行定制,ThreadFactory是一个接口,只有一个方法
public interface ThreadFactory {
	Thread newThread(Runnable r);
}
  1. RejectedExecutionHandler:当线程池中的资源已经全部使用,添加新线程被拒绝时,会调用RejectedExecutionHandler的rejectedExecution方法。 也是一个接口,只有一个方法。
public interface RejectedExecutionHandler {
	void rejectedExecution(Runnable var1, ThreadPoolExecutor var2);
}

线程池规则

线程池的线程执行规则跟任务队列有很大的关系。

  1. 线程数量<=核心线程数量
    那么直接启动一个核心线程来执行任务,不会放入队列中。
  2. 线程数量>核心线程数,但<=最大线程数,任务队列是LinkedBlockingDeque时
    超过核心线程数量的任务会放在任务队列中排队。
  3. 线程数量>核心线程数,但<=最大线程数,任务队列是SynchronousQueue时
    线程池会创建新线程执行任务,这些任务也不会被放在任务队列中。
    这些线程属于非核心线程,在任务完成后,闲置时间达到了超时时间就会被清除。
  4. 线程数量>核心线程数,并且>最大线程数,任务队列是LinkedBlockingDeque时
    会将超过核心线程的任务放在任务队列中排队。
  5. 线程数量>核心线程数,并且>最大线程数,任务队列是SynchronousQueue的时候,
    会因为线程池拒绝添加任务而抛出异常。

实例

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 一个简单的线程池使用示例
 */
public class TestThreadPoolExecutor {
	public static void main(String[] args) {
		// 核心线程数
		int corePoolSize = 2;
		// 最大线程数
		int maximumPoolSize = 10;
		// 非核心线程的闲置超时时间
		long keepAliveTime = 60;
		// keepAliveTime的单位
		TimeUnit unit = TimeUnit.SECONDS;
		// 线程池中的任务队列
		BlockingQueue<Runnable> workQueue = new LinkedBlockingDeque<>();
		
		ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue);
//		threadPoolExecutor.allowCoreThreadTimeOut(true);

		//调用execute执行任务
		for (int i = 0; i < maximumPoolSize + 1; i++) {
			threadPoolExecutor.execute(new Runnable() {
				@Override
				public void run() {
					System.out.println("threadName=" + Thread.currentThread().getName());
					try {
						Thread.sleep(1000 * 5);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			});
		}

		//终止空闲线程,并等待任务执行完成或超过10秒之后退出
		try {
			threadPoolExecutor.shutdown();
			threadPoolExecutor.awaitTermination(10, TimeUnit.SECONDS);
			System.exit(0);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值