JAVA线程池默认几种线程池的设计思想以及弊端

Java提供了4种线程池:

newCachedThreadPool

newFixedThreadPool

newSingleThreadExecutor

newScheduledThreadPool

你可以通过Executors来实例化这四种线程池。

查看源码会发现,这四种线程池都直接或者间接获取的ThreadPoolExecutor实例 ,只是实例化时传递的参数不一样。所以如果java提供的四种线程池满足不了我们的需求,我们可以创建自定义线程池。

ThreadPoolExecutor的构造方法如下:


如果你对这ThreadPoolExecutor不了解,可以参考有界、无界队列对ThreadPoolExcutor执行的影响

接下来我们来看下每种线程池的设计思想

newCachedThreadPool

它的实例化方法如下:

对于 CachedThreadPool 而言,为了避免新提交的任务被拒绝,它选择了无限制的 maximumPoolSize(Integer.MAX_VALUE),所以既然它的线程的最大数量是无限的,也就意味着它的线程数不会受到限制,那么它就不需要一个额外的空间来存储那些 Task,因为每个任务都可以通过新建线程来处理。

弊端

当一个任务提交时,corePoolSize为0不创建核心线程,SynchronousQueue是一个不存储元素的队列,可以理解为队列永远是满的,因此最终会创建非核心线程来执行任务。

对于非核心线程空闲60s时将被回收。因为Integer.MAX_VALUE非常大,可以认为是可以无限创建线程的,在资源有限的情况下容易引起OOM异常

newFixedThreadPool

采用的存储任务的队列是LinkedBlockingQueue ,默认是无界队列。


由于 FixedThreadPool 的线程数是固定的,在任务激增的时候,它无法增加更多的线程来帮忙处理 Task,所以需要像 LinkedBlockingQueue 这样没有容量上限的 Queue 来存储那些还没处理的 Task。
如果所有的 corePoolSize 线程都正在忙,那么新任务将会进入阻塞队列等待,由于队列是没有容量上限的,队列永远不会被填满,这样就保证了对于线程池 FixedThreadPool 和 SingleThreadExecutor 而言,不会拒绝新任务的提交,也不会丢失数据。

弊端:由于使用的是LinkedBlockingQueue无界队列,在资源有限的时候容易引起OOM异常

newSingleThreadExecutor

同newFixedThreadPool一样,只不过corePoolSize和maximumPoolSize都为1,但是由于采用的是无界队列,所以会导致OOM

newScheduledThreadPool

对于 ScheduledThreadPool 而言,它使用的是 DelayedWorkQueue。延迟队列的特点是:不是先进先出,而是会按照延迟时间的长短来排序,下一个即将执行的任务会排到队列的最前面。


我们来举个例子:例如我们往这个队列中,放一个延迟 10 分钟执行的任务,然后再放一个延迟 10 秒钟执行的任务。通常而言,如果不是延迟队列,那么按照先进先出的排列规则,也就是延迟 10 分钟执行的那个任务是第一个放置的,会放在最前面。但是由于我们此时使用的是阻塞队列,阻塞队列在排放各个任务的位置的时候,会根据延迟时间的长短来排放。所以,我们第二个放置的延迟 10 秒钟执行的那个任务,反而会排在延迟 10 分钟的任务的前面,因为它的执行时间更早。


我们选择使用延迟队列的原因是,ScheduledThreadPool 处理的是基于时间而执行的 Task,而延迟队列有能力把 Task 按照执行时间的先后进行排序,这正是我们所需要的功能。

弊端:同newCachedThreadPool一样,由于maximumPoolSize为最大整数,且队列使用的是DelayedWorkQueue无界队列,可呢个会导致OOM

总结:

综合来讲java提供的这4个线程池,由于【maximumPoolSize设置的是最大整数】或者【使用的队列是无界队列】,可能会导致OOM,所以不建议使用。应该根据自己的需要来通过ThreadPoolExecutor来构造自己的线程池

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Http Server线程池是用于处理HTTP请求的一种机制。在传统的方式中,每当有一个HTTP请求到来时,服务器会创建一个新的线程来处理该请求,然后在请求处理完成后销毁该线程。然而,这种方式的弊端是每次创建和销毁线程都需要一定的开销,而且线程数量的增加也限制了服务器的并发能力。 为了解决这个问题,引入了Http Server线程池。该线程池由预先创建的一组线程组成,这些线程可以反复使用。当有新的HTTP请求到来时,请求会被分配给空闲的线程进行处理,处理完成后线程回到线程池中,以供下一次请求使用。这种方式可以避免线程的频繁创建和销毁,提高了服务器的并发处理能力。 Http Server线程池的大小可以根据实际需求进行调整。如果请求量较大,可以增加线程池的大小,这样可以同时处理更多的请求,提高服务器的吞吐量。而如果请求量较小,可以减小线程池的大小,以节省资源。线程池的大小需要根据服务器的性能和负载情况进行合理的配置。 总之,Http Server线程池是一种提高服务器并发处理能力的机制。通过复用线程,避免了频繁创建和销毁线程的开销,同时可以根据实际需求调整线程池的大小,以达到最佳的性能和资源利用效果。 ### 回答2: HTTP服务器线程池是一种用于处理客户端请求的技术。在HTTP服务器中,每个客户端请求都需要一个单独的线程来进行处理。然而,如果同时有大量的客户端请求,那么就会创建大量的线程,这会导致系统资源的浪费和性能下降。 为了解决这个问题,可以使用线程池来管理和复用线程。线程池是一组预先创建的线程,它们可以在需要时被重新使用。当有新的请求到达时,服务器会将请求分发给线程池中的一个线程来处理,而不是为每个请求创建一个新线程。 通过使用线程池,服务器可以控制线程的数量,避免创建过多的线程而影响系统性能。线程池可以根据当前的负载情况动态地调整线程数量,以保持服务器的稳定和高效运行。 此外,线程池还可以提供其他的功能,比如设置超时时间、处理异常情况等。当线程池中的线程出现异常时,可以进行适当的处理,例如重新启动已经终止的线程,以保证服务器的稳定性。 总而言之,HTTP服务器线程池是一种优化服务器处理客户端请求的方式。通过合理管理和复用线程,可以提高服务器的性能和稳定性,减少资源的浪费。 ### 回答3: HTTP服务器线程池是一种常用的服务器设计模式,它通过创建一组线程来处理客户端的HTTP请求。该线程池中的每个线程都是一个可复用的工作单元,它们可以独立地处理一个或多个请求。以下是关于HTTP服务器线程池的详细解释: 1. 效率提升:使用线程池可以避免为每个请求都创建和销毁线程的开销。线程池中的线程可以被重复利用,客户端的请求可以并发地分配给不同的线程进行处理,从而提高服务器吞吐量。 2. 资源控制:线程池可以帮助服务器控制并发请求数量。通过限制线程池的大小,可以防止过多的线程同时对服务器进行请求,避免服务器资源过度耗费。 3. 请求处理组织:使用线程池可以将请求分配给可用的线程,并对请求进行排队和处理。线程池可以灵活地管理请求的优先级和等待时间,确保高优先级的请求能够尽快得到响应。 4. 并发控制:线程池可以限制线程的数量,避免过度并发造成系统崩溃或资源耗尽。同时,线程池可以根据服务器的硬件性能和处理能力进行动态调整,确保服务器的稳定性和可扩展性。 总而言之,HTTP服务器线程池是一种高效的服务器设计模式,通过合理地管理和利用线程,提高服务器的并发处理能力和性能。它可以实现请求的组织和调度,并限制并发请求数量,从而提供更好的用户体验和服务器响应速度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值