在Java并发编程中,如何扩展和优化线程池?

电脑信息 2022-08-01 设置问题 21 ℃
正文

在java中多线程并不陌生线程优先级设置,在一定的范围内,多线程数量的增加会明显提升整个系统的吞吐性能,但是线程本身会极大的耗费内存空间,线程的频繁创建和回收也极其占用CPU资源,多线程甚至会拖垮整个服务!

所以线程优先级设置,线程的利用必须掌握在一个度,太少的线程数可能会浪费CPU资源,而太高也极有可能反而降低整个应用性能;

线程池:基于使用多线程存在的问题,JDK提出了线程池技术,类似于数据库连接池,都是保持池中部分线程活跃状态,在需要使用线程的时候,直接从线程池中获取,使用线程优先级设置。当线程使用结束,就进行回收(直接放回池中等待,而不是GC),这样就能避免了线程的频繁创建和回收。

JAVA中的线程池:JDK提供了线程池框架Executor,帮助程序更好的管理线程线程优先级设置。总的结构如下截图:

在Java并发编程中,如何扩展和优化线程池?

比较常见的线程池对象获取方式为:

①newSingleThreadExecutor():返回单线程的线程池线程优先级设置,一个接一个的处理任务,线程异常的时候,会创建新的线程替代; ②newFixedThreadPool:在达到最大线程之前,有一个任务就创建一个线程,直到达到最大线程数量; ③newCachedThreadPool:动态的设置最合适的线程数量,最大为JVM能够支持的大小; ④newScheduledThreadPool:指定线程数量,并周期性的执行任务; ⑤newSingleThreadScheduledExecutor:指定线程数量1个,并周期性的执行任务;

从源码来看线程优先级设置,上面几种线程池底层都是封装的ThreadPoolExecutor对象,查看源码可知比较重要的属性(对象)截图如下:

在Java并发编程中,如何扩展和优化线程池?

在Java并发编程中,如何扩展和优化线程池?

定义了线程池中的线程数量线程优先级设置,最大线程池数量,线程工厂(用于线程的创建),workQuere任务队列,handler拒绝策略等属性,用于线程池的对象初始化和任务调度!

下图是ThreadPoolExecutor对象中的execute方法截图:

在Java并发编程中,如何扩展和优化线程池?

解释如下:

1线程优先级设置,当前线程总数小于核心线程数,则通过addWorker进行执行;

2线程优先级设置,否则通过wordQueue.offer提交到等待队列,

3线程优先级设置,进入等待队列失败,则通过addWorker提交到线程池,失败则执行拒绝策略;

线程池有多种拒绝策略:直接抛出异常,或者丢弃无法处理的任务等等,此处不做详细讨论线程优先级设置。。

线程池的扩展:JDK允许开发人员自主扩展线程池线程优先级设置,通过提供的beforeExecute,afterExecute,terminated三个接口可以像处理AOP一样方便的管理线程池,可自行实现状态跟踪,调试信息等用以监控线程池!

线程池的优化:线程池的优化主要针对线程数量进行线程优先级设置,一般来说只要使用的不是最大最小线程数量都可以,但是具体的还要根据场景,参考CPU核心数,等待时间等因素来判断最合适的线程数,比如是批量运算这种密集的CPU执行,则线程数设置为CPU核心数即可,如果有大量阻塞,则可以使用CPU核心数的偶数倍数,在有一本书中得出了一个公式如下截图:

在Java并发编程中,如何扩展和优化线程池?

jdk中的线程池技术比较完善,加上其他的多线程技术,促使JAVA成为高并发领域的佼佼者,最近一直在分享JAVA技术,得到很多朋友的鼓励,在此表示感谢,我也会一直持续的进行分享,敬请关注线程优先级设置。。

本文TAG:

最新文章
热门文章
标签列表
Zen Cart 中文版