首页 > 其他分享 >Executors线程池

Executors线程池

时间:2024-12-04 21:32:47浏览次数:4  
标签:Executors int 创建 线程 设置 CPU

Executors是一个线程池的工具类,提供了很多静态方法用于返回不同特点的线程池对象。

方法名称 说明
public static ExecutorService newFixedThreadPool(int nThreads) 创建固定线程数量的线程池,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程替代它。
public static ExecutorService newSingleThreadExecutor() 创建只有一个线程的线程池对象,如果该线程出现异常而结束,那么线程池会补充一个新线程。
public static ExecutorService newCachedThreadPool() 线程数量随着任务增加而增加,如果线程任务执行完毕且空闲了60s则会被回收掉,
public static ScheduledExecutorService newscheduledThreadPool(int corePoolsize) 创建一个线程池,可以实现在给定的延迟后运行任务或者定期执行任务。

注意:这些方法的底层,都是通过线程池的实现类ThreadPoolExecutor创建的线程池对象。

Executors使用可能存在的陷阱

大型并发系统环境中使用Executors如果不注意可能会出现系统风险。
阿里巴巴Java开发手册
【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors 返回的线程池对象的弊端如下:
1)FixedThreadPool和singleThreadPool:
允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM(内存溢出)。
2)CachedThreadPool和ScheduledThreadPool:
允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。

线程池的核心线程和最大连接的设置

配置线程池的核心线程数量(corePoolSize)和最大线程数量(maximumPoolSize)时,没有固定的公式,但可以根据具体的应用场景和系统资源进行合理设置。
以下是一些建议:

  • 核心线程数 (corePoolSize):

    • 对于CPU密集型任务,可以将核心线程数设置为 CPU 核心数 + 1,以充分利用 CPU 资源。
    • 对于IO密集型任务,可以将核心线程数设置得更高,因为 IO 操作会阻塞线程,更多的线程可以提高并发处理能力。
  • 最大线程数 (maximumPoolSize):

    • 最大线程数通常设置为核心线程数加上一个合理的额外线程数,以应对突发的高负载情况。
    • 一般情况下,最大线程数可以设置为 2 * CPU 核心数 或更高,具体取决于系统的内存和 CPU 资源。
  • 队列大小 (workQueue):

    • 队列大小也会影响线程池的性能。如果队列大小设置得过大,可能会导致大量任务积压,占用大量内存。
    • 如果队列大小设置得过小,可能会导致频繁创建新线程,增加系统开销。

综合考虑以上因素,可以参考以下公式进行配置:

int cpuCores = Runtime.getRuntime().availableProcessors();
int corePoolSize = cpuCores + 1; // CPU 密集型任务
// int corePoolSize = 2 * cpuCores; // IO 密集型任务
int maximumPoolSize = 2 * cpuCores;

当然,上述这些只是建议值,实际应用中需要根据具体的业务需求和系统资源进行调整。

其他常见问题

Executors工具类底层是基于什么方式实现的线程池对象?
线程池ExecutorService的实现类:ThreadPoolExecutor
Executors是否适合做大型互联网场景的线程池方案?
不合适。建议使用ThreadPoolExecutor来指定线程池参数,这样可以明确线程池的运行规则,规避资源耗尽的风险

标签:Executors,int,创建,线程,设置,CPU
From: https://www.cnblogs.com/Eduhg/p/18587160

相关文章

  • C++多线程之异步编程机制
    在C++11及以后的标准中,std::promise和std::future是用于在异步编程场景中实现线程间通信的重要工具。它们可以用来传递异步操作的结果,或者在任务完成时通知等待的线程。下面我将详细解释std::promise和std::future的实现机制,并提供一些使用场景和示例代码。实现机制std::pro......
  • 深入解析Java线程源码:从基础到并发控制的全面指南(一)
    一:Java线程基础和源码解析packagejava.lang;importjava.lang.ref.Reference;importjava.lang.ref.ReferenceQueue;importjava.lang.ref.WeakReference;importjava.security.AccessController;importjava.security.AccessControlContext;importjava.security.Pr......
  • 使用 Sentinel 实现请求限流、线程隔离、服务熔断和 Fallback 备用方案
    引言在微服务架构中,随着系统的复杂性和业务的增长,服务间的依赖关系也日益增多。在这种高并发、复杂的环境下,如何保证系统的高可用性、稳定性和可靠性,成为了开发者们的重要课题。为了应对这些挑战,服务容错与流量控制技术尤为重要。Sentinel,作为一个强大的分布式服务流量控制......
  • 深入理解Java内存模型与线程
    Java内存模型(JMM)是为了屏蔽底层硬件和操作系统的差异,使得Java程序在各种平台上都能获得一致的内存访问效果。随着多线程的普及,理解JMM以及Java线程的实现至关重要。本文将详细解析Java内存模型、线程实现及其状态转换。1.硬件的效率与一致性由于计算机的处理器与内存速度差......
  • go 多线程
    go多线程进程、线程、和协程进程分配系统资源(CPU时间、内存等)基本单位有独立的内存空间,切换开销大线程:进程的一个执行流,是CPU调度并能独立运行的的基本单位同一进程中的多线程共享内存空间,线程切换代价小多线程通信方便从内核层面来看线程其实也是一种特殊的进程......
  • 进程、线程、协程的关系
    系统和多个线程的关系:一个系统内可以创建多个进程,一个进程可以类比为一个应用程序,一个进程内可以创建多个线程,协程是Go语言首创,通过在一个线程内代理当前线程的所有系统的调度权,模拟出多个子线程——称作协程,以达到优化效率的目的。线程和协程的关系:协程Coroutine的精髓......
  • 【JavaEE初阶】落霞与孤鹜齐飞,秋水共长天一色 - (重点)线程
    本篇博客给大家带来的是线程的知识点,由于时间有限,分三天来写,本篇为线程第二篇.......
  • 突击检查:Java面试之多线程&并发篇(10)
    前言本来想着给自己放松一下,刷刷博客,突然被几道面试题难倒!说说CyclicBarrier和CountDownLatch的区别?什么是AQS?了解Semaphore吗?什么是Callable和Future?什么是阻塞队列?阻塞队列的实现原理是什么?如何使用阻塞队列来实现生产者-消费者模型?似乎有点模糊了,那就大概看一下面试题吧。好记......
  • Java 多线程探秘:核心概念与实用技巧全解析
    1.有三个线程T1,T2,T3,如何保证顺序执行?要确保三个线程T1,T2,和T3按顺序执行,你可以使用多种同步机制。以下是几种常见的方法:Join方法启动T1线程。调用T1.join(),这将使当前线程(假设是主线程)等待直到T1完成。启动T2线程,并调用T2.join()。最后启动T3线程,并......
  • Linux线程详解
    一、线程的概念        在引入线程之前,进程作为资源分配的最小单位(分配得到了CPU的时间、内存等),操作系统通过调度算法实现多进程并发执行,共用CPU,但由于创建或撤销进程时,系统都要为之分配或回收资源,限制了并发程度的提高。后来,为了减少进程间切换的开销,可把进程作为资......