线程池

举报
别团等shy哥发育 发表于 2023/10/18 14:42:09 2023/10/18
【摘要】 线程池Java的线程池是通过Executor框架实现的,在该框架中用到了Executor、Executors、ExecutorService、ThreadPoolExecutor、Callable、Future、FutureTask这几个核心类。 为什么用线程池?介绍下线程池的几个参数线程池的主要作用是线程复用、线程资源管理、控制操作系统的最大并发数,以保证系统高效(通过线程资源复用)和安...

线程池

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()可以接收CallableRunnable两种类型。Callable类型的任务是可以返回执行结果的,而Runnable类型的任务不可以返回执行结果。
  • submit()提交任务后会有返回值,而execute()没有:execute()方法主要用于启动任务的执行,而任务的执行结果和可能的异常调用者并不关心。submit()方法也用于启动任务的执行,但是启动之后会返回Future对象,代表一个异步执行实例,可以通过该异步执行实例去获取结果。
  • submit()方法Exception处理execute()方法在启动任务执行后,任务执行过程中可能发生的异常调用者并不关心。而通过submit()方法返回的Future对象(异步执行实例),可以进行异步执行过程中的异常捕获。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。