线程池
线程池
Java的线程池是通过Executor框架实现的,在该框架中用到了Executor、Executors、ExecutorService、ThreadPoolExecutor、Callable、Future、FutureTask这几个核心类。
为什么用线程池?介绍下线程池的几个参数
线程池的主要作用是线程复用、线程资源管理、控制操作系统的最大并发数,以保证系统高效(通过线程资源复用)和安全(通过控制最大并发线程数)的运行。
使用线程池可以降低资源消耗、提高响应速度、提高线程的可管理性,线程池ThreadPoolExecutor
参数如下:
corePoolSize
:线程池中核心线程数:任务队列未达到队列容量时,最大可以同时运行的线程数量。maximumPoolSize
:线程池中最大线程数。keepAliveTime
:当前线程数量大于核心线程数时,空闲线程的等待时间。unit
:keepAliveTime的时间单位。workQueue
:任务队列,被提交但尚未被执行的任务存放的地方。threadFactory
:线程工厂,用于创建线程,可使用默认的线程工厂或自定义线程工厂。handler
:拒绝策略,由于任务过多或其他原因导致线程池无法处理时的任务拒绝策略。
创建线程池的方法
创建线程池的方法:通过**Executors
工厂方法创建和通过new ThreadPoolExecutor
方法**创建
Executors
工厂方法创建,在工具类Executors提供了一些静态的工厂方法newFixedThreadPool
:创建固定大小的线程池。newCachedThreadPool
:创建一个带缓冲的线程池。newSingleThreadExecutor
:创建一个单线程的线程池。newScheduledThreadPool
:调度线程池,可以按照一定的周期执行任务,即定时任务。new ThreadPoolExecutor
创建:
new ThreadPoolExecutor(int corePoolSize, //核心线程数
int maximumPoolSize, //最大线程数
long keepAliveTime, //当前线程数量大于核心线程数时,空闲线程的等待时间
TimeUnit unit, //等待时间单位
BlockingQueue<Runnable> workQueue, //存放任务的阻塞队列
ThreadFactory threadFactory, //为线程池提供创建新线程的线程工厂
RejectedExecutionHandler handler)//拒绝策略
线程池的拒绝策略有哪些?
如果线程池中的核心线程被用完且阻塞队列已满,则此时线程池的线程资源已耗尽,线程池将没有足够的线程资源执行新的任务。为了保证操作系统的安全,线程池将通过拒绝策略处理新添加的线程任务。
AbortPolicy
:直接抛出异常,阻止线程正常运行(默认的拒绝策略)。CallerRunsPolicy
:调用者执行策略。在新任务被加到线程池时,如果添加失败,那么提交任务线程会自己去执行该任务,不会使用线程池中的线程去执行新任务。DiscardOldestPolicy
:抛弃最老任务策略。移除线程队列中最早的一个线程任务,并尝试提交当前任务。DiscardPolicy
:丢弃当前线程任务不做任何处理。- 自定义拒绝策略:实现
RejectedExecutionHandler
接口的rejectedExecution
方法。
向线程池提交任务的两种方式
(1)调用execute()
方法,例如:
//Executor接口中的方法
void execute(Runnable command);
(2)调用submit()
方法
//ExecutorService接口中的方法
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
execute和submit方法的区别是什么?
- 二者接收的参数不一样:
execute()
方法只能接收Runnable
类型,而submit()
可以接收Callable
、Runnable
两种类型。Callable
类型的任务是可以返回执行结果的,而Runnable
类型的任务不可以返回执行结果。 submit()
提交任务后会有返回值,而execute()
没有:execute()方法主要用于启动任务的执行,而任务的执行结果和可能的异常调用者并不关心。submit()方法也用于启动任务的执行,但是启动之后会返回Future对象,代表一个异步执行实例,可以通过该异步执行实例去获取结果。submit()
方法Exception
处理:execute()
方法在启动任务执行后,任务执行过程中可能发生的异常调用者并不关心。而通过submit()
方法返回的Future
对象(异步执行实例),可以进行异步执行过程中的异常捕获。
- 点赞
- 收藏
- 关注作者
评论(0)