首页 > 编程知识 正文

全局线程池和局部线程池,java线程池几个参数

时间:2023-05-04 14:05:06 阅读:151026 作者:2928

一.为什么要使用线程池

1、线程池优于单线程

a .重用存在的线程,减少创建和删除对象的开销,性能良好。

b .有效控制最大并发线程数量,提高系统资源利用率,同时避免资源过度竞争,避免拥堵。

c .提供定时执行、定期执行、单线程、并发数控制等功能。

2、使用场景

)1)当不需要有魅力的精灵任务时。 例如,线程池可以用于处理非阻塞任务,例如,记录操作日志或向第三方服务通知不需要的信息

)如果有吸引力的精灵任务需要花费时间,也可以采用线程池技术

)3)要求同时性高的情况下,可以使用线程池技术优化处理

二、创建线程池的几种方法

1、执行

Java通过Executors提供了四种类型的线程池:

)1) newCachedThreadPool )创建可缓存的线程池,如果线程池的长度超过处理所需的长度,则灵活地复用空闲线程,如果不能复用,则创建新线程。 (无法控制线程的最大并发行数。)

)2)创建固定长度线程池以控制newFixedThreadPool )线程的最大并发行数,超出的线程在队列中等待。

(3) newScheduledThreadPool )创建定长线程池,支持定时和周期性的任务执行。

)4) newSingleThreadExecutor )创建单线程化线程池,只通过唯一的工作线程执行任务,以便所有任务按指定顺序(FIFO、LIFO、优先级)执行

2、使用ThreadPoolExecutor

三.为什么不允许使用Executors创建线程池

不允许使用《阿里巴巴Java开发手册》执行程序创建线程池

总结:

创建封装在Executors类中的线程池的方法易于使用,但由于存在局限性和风险,因此通过使用ThreadPoolExecutor类的构建方法手动创建线程池实例,并根据使用情况指定参数

因此,使用Executors类创建线程池与使用ThreadPoolExecutor类的区别在于通过使用ThreadPoolExecutor类传递给设置的线程池的参数

四.创建线程池,建议使用ThreadPoolExecutor

一、若干重要结构参数

(1) corePoolSize :

除非设置了线程超时时间,否则即使未使用这些线程,线程池中保留的线程数也是如此

)2) maximumPoolSize :

最大线程数。 workQueue队列已满,无法放置新任务,当您在execute中添加新任务时,线程池将创建新线程。 线程数大于corePoolSize,但不会超过maximumPoolSize。 如果超过maximumPoolSize,则会抛出异常,如rejecececolsize

(3) keepAliveTime和unit

如果线程池中的线程数大于workQueue,并且线程空闲时间长于keepAliveTime,则线程将被丢弃。 unit是keepAliveTime的时间单位。

(4)工作队列

阻止队列。 如果线程池中运行的线程数达到corePoolSize,则在execute中添加新任务会将其添加到workQueue队列中,并排队等待执行,而不会立即执行。

5 ) RejectedExecutionHandler提交任务数超过maximumPoolSize workQueue之和时,任务将交给RejectedExecutionHandler进行处理

其中rejectedExecutionHandler字段用于设置拒绝策略,常见的拒绝策略如下:

AbortPolicy,被拒绝任务的处理程序。 抛出RejectedExecutionException。

CallerRunsPolicy是拒绝任务的处理程序,直接在execute方法的调用线程中执行拒绝的任务。

分散性。 在任务被拒绝的处理程序中,放弃最早的未完成请求,然后重试执行。

DiscardPolicy是拒绝任务的处理程序,缺省情况下将丢弃拒绝的任务。

流程:

corePoolSize、maximumPoolSize、workQueue三者之间的关系

1 )如果线程池小于corePoolSize,则新提交的任务将创建新的线程执行任务,即使线程池中还有空闲线程。

2 )线程池达到corePoolSize后,新提交的任务将放入工作队列中,等待线程池中的任务完成

3 )当workQueue已满且变为maximumPoolSize corePoolSize时,新的提交任务将创建新的线程执行任务

4 )提交任务数较多时

过maximumPoolSize,新任务就交给RejectedExecutionHandler来处理

5)当线程池中超过 corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程

6)当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭

2、spring中如何使用ThreadPoolExecutor创建线程池

ThreadPoolTaskExecutor是一个spring的线程池技术,它是使用jdk中的java.util.concurrent.ThreadPoolExecutor进行实现。

(1)XML配置

(2)bean中使用

private ThreadPoolTaskExecutor taskExecutor;

taskExecutor.execute(new Thread(.....));

五、考试

现有一个线程池,参数corePoolSize = 5,maximumPoolSize = 10,BlockingQueue阻塞队列长度为5,此时有4个任务同时进来,问:线程池会创建几条线程?

如果4个任务还没处理完,这时又同时进来2个任务,问:线程池又会创建几条线程还是不会创建?

如果前面6个任务还是没有处理完,这时又同时进来5个任务,问:线程池又会创建几条线程还是不会创建?

回答:

线程池corePoolSize=5,线程初始化时不会自动创建线程,所以当有4个任务同时进来时,执行execute方法会新建【4】条线程来执行任务;

前面的4个任务都没完成,现在又进来2个队列,会新建【1】条线程来执行任务,这时poolSize=corePoolSize,还剩下1个任务,线程池会将剩下这个任务塞进阻塞队列中,等待空闲线程执行;

如果前面6个任务还是没有处理完,这时又同时进来了5个任务,此时还没有空闲线程来执行新来的任务,所以线程池继续将这5个任务塞进阻塞队列,但发现阻塞队列已经满了,核心线程也用完了,还剩下1个任务不知道如何是好,于是线程池只能创建【1】条“临时”线程来执行这个任务了;

这里创建的线程用“临时”来描述还是因为它们不会长期存在于线程池,它们的存活时间为keepAliveTime,此后线程池会维持最少corePoolSize数量的线程。

六、写到最后

作者:极致研发部--申冠豪

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。