网站的建设和设计方案,国内简约网站设计欣赏,建设部执业资格网站,发展速度迅猛 具有丰富的网站建设经验1、什么是线程池
java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池
多线程技术主要解决处理器单元内多个线程执行的问题#xff0c;它可以显著减少处理器单元的闲置时间#xff0c;增加处理器单元的吞吐能力。 假设一个服…1、什么是线程池
java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池
多线程技术主要解决处理器单元内多个线程执行的问题它可以显著减少处理器单元的闲置时间增加处理器单元的吞吐能力。 假设一个服务器完成一项任务所需时间为T1 创建线程时间T2 在线程中执行任务的时间T3 销毁线程时间。
如果T1 T3 远大于 T2则可以采用线程池以提高服务器性能。 一个线程池包括以下四个基本组成部分 1、线程池管理器ThreadPool用于创建并管理线程池包括 创建线程池销毁线程池添加新任务 2、工作线程PoolWorker线程池中线程在没有任务时处于等待状态可以循环的执行任务 3、任务接口Task每个任务必须实现的接口以供工作线程调度任务的执行它主要规定了任务的入口任务执行完后的收尾工作任务的执行状态等 4、任务队列taskQueue用于存放没有处理的任务。提供一种缓冲机制。 线程池技术正是关注如何缩短或调整T1,T3时间的技术从而提高服务器程序性能的。它把T1T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段这样在服务器程序处理客户请求时不会有T1T3的开销了。 线程池不仅调整T1,T3产生的时间段而且它还显著减少了创建线程的数目看一个例子 假设一个服务器一天要处理50000个请求并且每个请求需要一个单独的线程完成。在线程池中线程数一般是固定的所以产生线程总数不会超过线程池中线程的数目而如果服务器不利用线程池来处理这些请求则线程总数为50000。一般线程池大小是远小于50000。所以利用线程池的服务器程序不会为了创建50000而在处理请求时浪费时间从而提高效率。
2.常见线程池
①newSingleThreadExecutor 单个线程的线程池即线程池中每次只有一个线程工作单线程串行执行任务 ②newFixedThreadExecutor(n) 固定数量的线程池没提交一个任务就是一个线程直到达到线程池的最大数量然后后面进入等待队列直到前面的任务完成才继续执行 ③newCacheThreadExecutor推荐使用 可缓存线程池当线程池大小超过了处理任务所需的线程那么就会回收部分空闲一般是60秒无执行的线程当有任务来时又智能的添加新线程来执行。 ④newScheduleThreadExecutor 大小无限制的线程池支持定时和周期性的执行线程
java提供的线程池更加强大相信理解线程池的工作原理看类库中的线程池就不会感到陌生了。 要配置一个线程池是比较复杂的尤其是对于线程池的原理不是很清楚的情况下很有可能配置的线程池不是较优的因此在Executors类里面提供了一些静态工厂生成一些常用的线程池。
2.1 newSingleThreadExecutor
创建一个单线程的线程池。这个线程池只有一个线程在工作也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
2.2 newFixedThreadPool
创建固定大小的线程池。每次提交一个任务就创建一个线程直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变如果某个线程因为执行异常而结束那么线程池会补充一个新线程。
2.3 newCachedThreadPool
创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程
那么就会回收部分空闲60秒不执行任务的线程当任务数增加时此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制线程池大小完全依赖于操作系统或者说JVM能够创建的最大线程大小。
2.4 newScheduledThreadPool
创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。
3 为什么不建议使用 Executors静态工厂构建线程池
阿里巴巴Java开发手册明确指出不允许使用Executors静态工厂构建线程池 原因如下 线程池不允许使用Executors去创建而是通过ThreadPoolExecutor的方式这样的处理方式让写的同学更加明确线程池的运行规则规避资源耗尽的风险
说明Executors返回的线程池对象的弊端如下
1FixedThreadPool 和 SingleThreadPool 允许的请求队列底层实现是LinkedBlockingQueue长度为Integer.MAX_VALUE可能会堆积大量的请求从而导致OOM 2CachedThreadPool 和 ScheduledThreadPool 允许的创建线程数量为Integer.MAX_VALUE可能会创建大量的线程从而导致OOM。 创建线程池的正确姿势
避免使用Executors创建线程池主要是避免使用其中的默认实现那么我们可以自己直接调用ThreadPoolExecutor的构造函数来自己创建线程池。在创建的同时给BlockQueue指定容量就可以了。
private static ExecutorService executor new ThreadPoolExecutor(10, 10,60L, TimeUnit.SECONDS,new ArrayBlockingQueue(10));或者是使用开源类库开源类库如apache和guava等。
3、线程池常用参数
/*** Creates a new {code ThreadPoolExecutor} with the given initial* parameters.** param corePoolSize the number of threads to keep in the pool, even* if they are idle, unless {code allowCoreThreadTimeOut} is set* param maximumPoolSize the maximum number of threads to allow in the* pool* param keepAliveTime when the number of threads is greater than* the core, this is the maximum time that excess idle threads* will wait for new tasks before terminating.* param unit the time unit for the {code keepAliveTime} argument* param workQueue the queue to use for holding tasks before they are* executed. This queue will hold only the {code Runnable}* tasks submitted by the {code execute} method.* param threadFactory the factory to use when the executor* creates a new thread* param handler the handler to use when execution is blocked* because the thread bounds and queue capacities are reached* throws IllegalArgumentException if one of the following holds:br* {code corePoolSize 0}br* {code keepAliveTime 0}br* {code maximumPoolSize 0}br* {code maximumPoolSize corePoolSize}* throws NullPointerException if {code workQueue}* or {code threadFactory} or {code handler} is null*/public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueRunnable workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) { }corePoolSize核心线程数量会一直存在除非allowCoreThreadTimeOut设置为true maximumPoolSize线程池允许的最大线程池数量 keepAliveTime线程数量超过corePoolSize空闲线程的最大超时时间 unit超时时间的单位 workQueue工作队列保存未执行的Runnable 任务 threadFactory创建线程的工厂类 handler当线程已满工作队列也满了的时候会被调用。被用来实现各种拒绝策略。