精华内容
下载资源
问答
  • maximunPoolSize:最大线程数 每当有新的任务到线程池时,第一步: 先判断线程池中当前线程数量是否达到了corePoolSize,若未达到,则新建线程运行此任务,且任务结束后将该线程保留在线程池中,不做销毁处理,若...

    线程池策略

    corePoolSize:核心线程数;maximunPoolSize:最大线程数

    每当有新的任务到线程池时,
    第一步: 先判断线程池中当前线程数量是否达到了corePoolSize,若未达到,则新建线程运行此任务,且任务结束后将该线程保留在线程池中,不做销毁处理(如果来了新的任务有空闲的核心线程,则不创建新的线程,使用空闲核心线程执行任务),若当前线程数量已达到corePoolSize,则进入下一步;
    第二步: 判断工作队列(workQueue)是否已满,未满则将新的任务提交到工作队列中,满了则进入下一步;
    第三步: 判断线程池中的线程数量是否达到了maxumunPoolSize,如果未达到,则新建一个工作线程来执行这个任务,如果达到了则使用饱和策略来处理这个任务。注意: 在线程池中的线程数量超过corePoolSize时,每当有线程的空闲时间超过了keepAliveTime,这个线程就会被终止。直到线程池中线程的数量不大于corePoolSize为止。
    (由第三步可知,在一般情况下,Java线程池中会长期保持corePoolSize个线程。)

    饱和策略

    当工作队列满且线程个数达到maximunPoolSize后所采取的策略
    AbortPolicy:默认策略;新任务提交时直接抛出未检查的异常RejectedExecutionException,该异常可由调用者捕获。
    CallerRunsPolicy:既不抛弃任务也不抛出异常,使用调用者所在线程运行新的任务。
    DiscardPolicy:丢弃新的任务,且不抛出异常。
    DiscardOldestPolicy:调用poll方法丢弃工作队列队头的任务,然后尝试提交新任务
    自定义策略:根据用户需要定制。

    到此Java 线程池核心线程数与最大线程数的区别介绍完成。

    展开全文
  • Java线程池的核心线程数最大线程数

    千次阅读 多人点赞 2021-03-14 19:24:35
    Java的线程池就像是一个花瓶容器。 而把任务提交给线程池就像是把小球塞进花瓶。 整个过程就像下面这个有趣的动画: 下面我们先来了解一下Java线程池的参数。 希望看完这篇文章后, 再提起线程池的时候, 你脑海...

    Java的线程池就像是一个花瓶容器。

    而把任务提交给线程池就像是把小球塞进花瓶。

    整个过程就像下面这个有趣的动画:

    下面我们先来了解一下Java线程池的参数。

    希望看完这篇文章后, 再提起线程池的时候, 你脑海首先出现的, 会是一个花瓶 : )


    线程池的参数意义

    Java线程池的构造函数如下:

    public ThreadPoolExecutor(
      int corePoolSize,
      int maximumPoolSize,
      long keepAliveTime,
      TimeUnit unit,
      BlockingQueue<Runnable> workQueue,
      ThreadFactory threadFactory,
      RejectedExecutionHandler handler) {
        //...
    }

    线程池有这么几个重要的参数:

    • corePoolSize=> 线程池里的核心线程数量
    • maximumPoolSize=> 线程池里允许有的最大线程数量
    • keepAliveTime=> 空闲线程存活时间
    • unit=> keepAliveTime的时间单位,比如分钟,小时等
    • workQueue=> 缓冲队列
    • threadFactory=> 线程工厂用来创建新的线程放入线程池
    • handler=> 线程池拒绝任务的处理策略,比如抛出异常等策略

    线程池大体的原理就是这样的:corePoolSize ->queue -> maxPoolSzie , 吧啦吧啦......

    那么现在重点来了, 这堆参数解释不看源码真的搞不懂怎么办?

    或者你看懂了这些参数的文字解析,但是到用的时候总是记不住怎么办?

    或者我们来一组实际参数,你能理解这代表的含义吗?

    corePoolSize:1
    mamximumPoolSize:3
    keepAliveTime:60s
    workQueue:ArrayBlockingQueue,有界阻塞队列,队列大小是4
    handler:默认的策略,抛出来一个ThreadPoolRejectException

    别慌,我们可以把线程池的参数做成花瓶的参数,这样一来很多东西就不言自明了。

    线程池的参数可视化

    我们回到前面所说的花瓶。

    这个花瓶由 瓶口 、 瓶颈 、 瓶身 三个部分组成。

    这三个部分分别对应着线程池的三个参数:maximumPoolSize, workQueue,corePoolSize。

    线程池里的线程,我用一个红色小球表示,每来一个任务,就会生成一个小球:

    而核心线程,也就是正在处理中的任务,则用灰色的虚线小球表示 (目前第一版动画先这样简陋点吧......)

    于是画风就变成了这样,“花瓶”有这么几个重要的参数:

    • corePoolSize=> 瓶身的容量
    • maximumPoolSize=> 瓶口的容量
    • keepAliveTime=> 红色小球的存活时间
    • unit=> keepAliveTime的时间单位,比如分钟,小时等
    • workQueue=> 瓶颈,不同类型的瓶颈容量不同
    • threadFactory=> 你投递小球进花瓶的小手 (线程工厂)
    • handler=> 线程池拒绝任务的处理策略,比如小球被排出瓶外

    如果往这个花瓶里面放入很多小球时(线程池执行任务);

    瓶身 (corePoolSize) 装不下了, 就会堆积到 瓶颈 (queue) 的位置;

    瓶颈还是装不下, 就会堆积到 瓶口 (maximumPoolSize);

    直到最后小球从瓶口溢出。

    还记得上面提到的那一组实际参数吗,代表的花瓶大体上是如下图这样的:

    那么参数可视化到底有什么实际意义呢?


    3 阿里的规范

    首先我们来看阿里开发手册中对于 Java 线程池的使用规范:

    为什么规范中提及的四种线程会导致OOM呢?

    我们看看这四种线程池的具体参数,然后再用花瓶动画演示一下导致OOM的原因。

    线程池FixedThreadPool

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
        0L, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<Runnable>());

    我们关心的参数如下

    corePoolSize:nThreads
    mamximumPoolSize:nThreads
    workQueue:LinkedBlockingQueue

    FixedThreadPool表示的花瓶就是下图这样子:

    线程池SingleThreadPool:

    public static ExecutorService newSingleThreadExecutor() {
          return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
             0L, TimeUnit.MILLISECONDS,
             new LinkedBlockingQueue<Runnable>()));
    ​  }

    我们关心的参数如下

    corePoolSize:1
    mamximumPoolSize:1
    workQueue:LinkedBlockingQueue

    SingleThreadPool表示的花瓶就是下图这样子:


    虽然两个线程池的样子没什么差异,但是这里我们发现了一个问题:

    为什么 FixedThreadPool 和 SingleThreadPool 的 corePoolSize和mamximumPoolSize 要设计成一样的?

    回答这个问题, 我们应该关注一下线程池的 workQueue 参数。

    线程池FixedThreadPool和SingleThreadPool 都用到的阻塞队列 LinkedBlockingQueue。

    LinkedBlockingQueue

    The capacity, if unspecified, is equal to {@link Integer#MAX_VALUE}. Linked nodes are dynamically created upon each insertion unless this would bring the queue above capacity.

    从LinkedBlockingQueue的源码注释中我们可以看到, 如果不指定队列的容量, 那么默认就是接近无限大的。

    从动画可以看出, 花瓶的瓶颈是会无限变长的, 也就是说不管瓶口容量设计得多大, 都是没有作用的!

    所以不管线程池FixedThreadPool和SingleThreadPool 的mamximumPoolSize 等于多少, 都是不生效的!


    线程池CachedThreadPool

    public static ExecutorService newCachedThreadPool() {
      return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
      60L, TimeUnit.SECONDS,
      new SynchronousQueue<Runnable>());

    我们关心的参数如下

    corePoolSize:0
    mamximumPoolSize:Integer.MAX_VALUE
    workQueue:SynchronousQueue

    表示的花瓶就是下图这样子:

    这里我们由发现了一个问题:

    为什么CachedThreadPool的mamximumPoolSize要设计成接近无限大的?

    回答这个问题, 我们再看一下线程池CachedThreadPool的 workQueue 参数:SynchronousQueue。

    SynchronousQueue

    来看SynchronousQueue的源码注释:

    A synchronous queue does not have any internal capacity, not even a capacity of one.

    从注释中我们可以看到, 同步队列可以认为是容量为0。

    所以如果mamximumPoolSize不设计得很大, 就很容易导致溢出。

    但是瓶口设置得太大,堆积的小球太多,又会导致OOM(内存溢出)。

    线程池ScheduledThreadPool

    public ScheduledThreadPoolExecutor(int corePoolSize) {
      super(corePoolSize, Integer.MAX_VALUE, 
      0, NANOSECONDS,
      new DelayedWorkQueue());
    }

    我们关心的参数如下

    corePoolSize:corePoolSize
    mamximumPoolSize:Integer.MAX_VALUE
    workQueue:DelayedWorkQueue

    可以看到, 这里出现了一个新的队列 workQueue:DelayedWorkQueue

    DelayedWorkQueue

    DelayedWorkQueue 是无界队列, 基于数组实现, 队列的长度可以扩容到 Integer.MAX_VALUE。

    同时ScheduledThreadPool的 mamximumPoolSize 也是接近无限大的。

    可以想象得到,ScheduledThreadPool就是史上最强花瓶, 极端情况下长度已经突破天际了!

    到这里, 相信大家已经明白, 为什么这四种线程会导致OOM了。

    怎么感觉这四种线程还真是名副其实的“花瓶”呢 :)


    后续

    目前花瓶动画还只是粗略的版本, 有部分瑕疵是不可避免的, 根据二八定律, 我的主要想法大体上是先做出来了,剩下的细节再慢慢补。

    目前只体现了线程池的三个参数。

    如果现在加入参数 keepAliveTime, 那么动画又会有什么效果的呢?

    敬请期待后续更新的文章。


    可视化的意义

    有很多人或许会认为, 学习个线程池, 还要做什么动画, 这不是走偏了吗?

    引用大神的一句话回答这个问题:

    Data visualization knowledge is not necessary -- just the desire to spread some knowledge.

    —— Ben Johnson

    数据可视化确实不是必需的, 但是有时候我们仅仅只是渴望给大家分享一些知识。

    而且在这个分享的过程中, 动画会让你做出更多的思考:

    思考动画怎么才能符合真实场景的效果。

    比如当我们开始思考,动画中花瓶颈部的长度变化,以及DelayedWorkQueue队列容量的变化,这两者如何才能对应的上时,于是不可避免的, 我们会开始研究起DelayedWorkQueue的扩容方式

    甚至每一种队列都可以单独展开做成更加细化的动画。

    而想要做好这些动画, 又要开始研究不同队列的源码了, 有需求才有动力!

    /**
     * 简单配置示例
     */
    
    //获取当前机器的核数
    public static final int cpuNum = Runtime.getRuntime().availableProcessors();
    
    @Override
        public Executor getAsyncExecutor() {
            ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            taskExecutor.setCorePoolSize(cpuNum);//核心线程大小
            taskExecutor.setMaxPoolSize(cpuNum * 2);//最大线程大小
            taskExecutor.setQueueCapacity(500);//队列最大容量
            //当提交的任务个数大于QueueCapacity,就需要设置该参数,但spring提供的都不太满足业务场景,可以自定义一个,也可以注意不要超过QueueCapacity即可
            taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
            taskExecutor.setAwaitTerminationSeconds(60);
            taskExecutor.setThreadNamePrefix("BCarLogo-Thread-");
            taskExecutor.initialize();
            return taskExecutor;
        }
    
    

     

    展开全文
  • Linux最大线程数限制及当前线程数查询1、总结系统限制有:/proc/sys/kernel/pid_max #查系统支持的最大线程数,一般会很大,相当于理论值/proc/sys/kernel/thread-maxmax_user_process(ulimit -u) #系统限制某用户下...

    Linux最大线程数限制及当前线程数查询

    1、总结系统限制有:

    /proc/sys/kernel/pid_max #查系统支持的最大线程数,一般会很大,相当于理论值

    /proc/sys/kernel/thread-max

    max_user_process(ulimit -u) #系统限制某用户下最多可以运行多少进程或线程

    /proc/sys/vm/max_map_count

    硬件内存大小

    2、Java虚拟机本身限制:

    -Xms  #intial java heap size

    -Xmx  #maximum java heap size

    -Xss  #the stack size for each thread

    3、查询当前某程序的线程或进程数

    pstree -p `ps -e | grep java | awk '{print $1}'` | wc -l

    pstree -p 3660 | wc -l

    4、查询当前整个系统已用的线程或进程数

    pstree -p | wc -l

    1、 cat /proc/${pid}/status

    2、pstree -p ${pid}

    3、top -p ${pid} 再按H  或者直接输入 top -bH -d 3 -p  ${pid}

    top -H

    手册中说:-H : Threads toggle

    加上这个选项启动top,top一行显示一个线程。否则,它一行显示一个进程。

    4、ps xH

    手册中说:H Show threads as if they were processes

    这样可以查看所有存在的线程。

    5、ps -mp

    手册中说:m Show threads after processes

    这样可以查看一个进程起的线程数。

    0b1331709591d260c1c78e86d0c51c18.png

    展开全文
  • 2019独角兽企业重金招聘... 一天,程序崩溃:## There is insufficient memory for the Java Runtime Environment to continue.# Native memory allocation (malloc) failed to allocate 32756 bytes for ChunkPo...

    2019独角兽企业重金招聘Python工程师标准>>>

    6936d1565ae689371725cdb5fc51c415.png

    一天,程序崩溃:

    #

    # There is insufficient memory for the Java Runtime Environment to continue.

    # Native memory allocation (malloc) failed to allocate 32756 bytes for ChunkPool::allocate

    # Possible reasons:

    #   The system is out of physical RAM or swap space

    #   In 32 bit mode, the process size limit was hit

    # Possible solutions:

    #   Reduce memory load on the system

    #   Increase physical memory or swap space

    #   Check if swap backing store is full

    #   Use 64 bit Java on a 64 bit OS

    #   Decrease Java heap size (-Xmx/-Xms)

    #   Decrease number of Java threads

    #   Decrease Java thread stack sizes (-Xss)

    #   Set larger code cache with -XX:ReservedCodeCacheSize=

    # This output file may be truncated or incomplete.

    #

    #  Out of Memory Error (allocation.cpp:211), pid=3696, tid=3704

    #

    # JRE version: 6.0_26-b03

    # Java VM: Java HotSpot(TM) Client VM (20.1-b02 mixed mode, sharing windows-x86 )

    ------------------------------------------------下面是用google翻译的

    #有针对Java运行环境继续内存不足。

    #本机内存分配(malloc的)未能分配ChunkPool32756字节:分配

    #可能的原因:

    #该系统是出了物理RAM或交换空间

    #在32位模式下,进程大小限制被击中

    #可能的解决方案:

    #减少内存系统上的负载

    #增加物理内存或交换空间

    #检查交换后备存储已满

    #使用64位操作系统上的64位Java

    #减少Java堆大小(-Xmx/-Xms)

    #减少Java的线程数

    #减少Java线程堆栈大小(- XSS)**********

    #设置更大的代码缓存使用- XX:ReservedCodeCacheSize=

    #这个输出文件可能被截断或不完整的。

    #内存不足的错误(allocation.cpp:211),PID=3696,TID=3704

    #JRE版本:6.0_26- B03

    #Java虚拟机:的Java HotSpot(TM)客户端虚拟机(20.1- B02混合模式,共享窗口- X86)

    ----------------------------------------------------

    我看了一下日志,线程数在3000多个,我了解的也是这样,当线程超过3000多的时候,就出内存问题。

    下面是摘抄网上关于JVM线程堆栈的相关内容:

    JVM线程堆栈

    应用程序中的每个线程都需要内存来存储器堆栈(用于在调用函数时持有局部变量并维护状态的内存区域)。每个 Java 线程都需要堆栈空间来运行。

    根据实现的不同,Java 线程可以分为本机线程和 Java 堆栈。除了堆栈空间,每个线程还需要为线程本地存储(thread-local storage)和内部数据结构提供一些本机内存。

    JVM堆栈大小

    -Xss 128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆 栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。

    在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一 个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。

    JVM heap与JVM私有内存、JVM线程堆栈大小间的关系及平衡。

    线程栈的大小是个双刃剑,如果设置过小,可能会出现栈溢出,特别是在该线程内有递归、大的循环时

    时出现溢出的可能性更大,如果该值设置过大,就有影响到创建栈的数量,如果是多线程的应用,就会

    出现内存溢出的错误.

    展开全文
  • 线程池 最大线程数

    2021-03-07 04:28:39
    java.lang.OutOfMemoryError: unable to create new native threadat java.lang.Thread.start0(Native Method) ~[na:1.7.0_45]at java.lang.Thread.start(Thread.java:713) ~[na:1.7.0_45]at java.util.concurrent.T...
  • 这几天因为自己开发的一个网站在768M内存的机器上撑不起100多个用户的运行,因为每个用户启用功能后,系统将为每个用户分配8个左右的独立线程,我的这篇文章http://www.mzone.cc/article/311.html也有介绍的。...
  • 皇叔6分钟速读仅需3分钟McGovernTheory在StackOverflow提了这样一个问题:Java虚拟机最多支持多少个线程?跟虚拟机开发商有关么?跟操作系统呢?还有其他的因素吗?Eddie的回答:这取决于你使用的CPU,操作系统,其他...
  • s 一个信息头 l 多线程(使用 CLONE_THREAD,像NPTL的pthreads的那样) + 在前台进程组 使用pstree命令 ##打印所有进程及其线程 pstree -p ##打印某个进程的线程数 pstree -p {pid} | wc -l 超过系统最大线程数 ##...
  • On several posts as: Java virtual machine - maximum number of threads https://community.oracle.com/message/10312772 people are stating that they run thousands of java threads concurrently on normal ...
  • 任何人都可以告诉我们如何决定我们应该使用哪些最大线程以获得更好的性能 – 它绝对不是最大线程数量.为获得最佳性能,线程数量应等于处理器核心数量(不要忘记使用-XmsYYYYM和-XmxYYYYM,如果没有它们,您可能会遇到...
  • (1)线程的生命周期开销非常高 (2)消耗过多的CPU 资源 如果可运行的线程数量多于可用处理器的数量,那么有线程将会被闲置。大量空闲的线程会占用许多内存,给垃圾回收器带来压力,而且大量的线程在竞争CPU 资源时...
  • 一、需求缘起Web-Server通常有个配置,最大工作线程数,后端服务一般也有个配置,工作线程池的线程数量,这个线程数的配置不同的业务架构师有不同的经验值,有些业务设置为CPU核数的2倍,有些业务设置为CPU核数的8倍...
  • 在高并发的情况下采用线程池,可以有效降低线程创建释放的时间花销及资源开销,如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存以及“过度切换”(在JVM中采用的处理机制为时间片轮转,减少了线程间...
  • 整理于 java进程 jvm 线程数量_jvm最大线程数 这篇文章分为三个部分:认识问题、分析问题、解决问题。 一、认识问题: 首先我们通过下面这个 测试程序 来认识这个问题: 运行的环境 (有必要说明一下,不同环境会有...
  • ThreadPoolExecutor是JDK中的线程池实现,这个类实现了一个线程池需要的各个方法,它实现了任务提交、线程管理、监控等等方法。 来看看ThreadPoolExecutor类的构造方法源码,其他创建线程池的方法最终都会导向这个...
  • jvm最大线程数

    2021-03-13 01:15:53
    一、认识问题:首先我们通过下面这个 测试程序 来认识这个问题:运行的环境 (有必要说明一下,不同环境会有不同的结果):32位 Windows XP,Sun JDK1.6.0_18, eclipse 3.4,测试程序:Java代码 import java.util....
  • 您可以使用sample program来...在小型内存机器中每个Java线程都使用自己的堆栈内存.默认堆栈大小为1024k(= 1M).您可以减少堆栈大小,如java -Xss512k ….如果堆栈大小太小,则无法启动JVM.并注意堆内存配置:(初始)-Xm...
  • 每个线程都有一个线程栈空间通过-Xss设置,查了一下我们服务器的关于jvm内存的...-XX:ThreadStackSize 设置线程数大小,会反向设置-Xss大小 可以通过如下命令打印输出默认值的大小,命令:jinfo -flag ThreadStackSize
  • 线程数:是同一时刻设备能并行执行的程序个线程数=cpu个 * 核数二 cpu线程数Java线程首先明白几个概念:(1) 单个cpu线程在同一时刻只能执行单一Java程序,也就是一个线程(2) 单个线程同时只能在单个cpu...
  • 一、JVM(JDK)最大线程JVM最大创建线程数量由JVM堆内存大小、线程的Stack内存大小、系统最大可创建线程(Java线程的实现是基于底层系统的线程机制来实现的,Windows下_beginthreadex,Linux下pthread_create)三个...
  • 线程池的初始参数中包含 核心线程数最大线程数、线程池线程空闲回收时间、阻塞队列、线程工厂、拒绝策略。 那么线程池是如何管理线程和阻塞队列的关系呢? 验证思路 确保先提交的任务优先被线程池处理 多线程执行...
  • 1、总结系统限制有:/proc/sys/kernel/pid_max #查系统支持的最大线程数,一般会很大,相当于理论值/proc/sys/kernel/thread-maxmax_user_process(ulimit -u) #系统限制某用户下最多可以运行多少进程或线程/proc/sys...
  • 合理设置工作线程数

    2021-03-13 09:06:03
    最大工作线程数,后端服务一般也有个配置,工作线程池的线程数量,这个线程数的配置不同的业务架构师有不同的经验值,有些业务设置为CPU核数的2倍,有些业务设置为CPU核数的8倍,有些业务设置为CPU核数的32倍。...
  • When we start threads in a Java program, is there any way for us to assign memory limit to each one of them?I mean we assign something like this for a new Java process:/usr/java/default/bin/java -Xms5...
  • 一、前言Tomcat 作为 Java Web 程序比较常用的 Servlet ...在 Tomcat7 及以下 Linux 中默认启用的是 BIO 模式,Tomcat8 及以上使用的是 NIO 模式,利用 Java 的异步 IO 处理,可以通过少量的线程处理大量的连接请求...
  • 裹在Delayed一个实现由此Delayed的getDelay(TimeUnit)方法返回所讨论的工作的最大执行时间Future。 public class DelayedImpl implements Delayed { private final long maxExecTimeMillis; private final Future ...
  • tomcat启动后老是报错:java.lang.OutOfMemoryError: unable to create new native thread,刚开始以为内存不够就增加tomcat内存:JAVA_OPTS="-server -XX:PermSize=1024M -XX:MaxPermSize=2048m -...
  • 作者:miracle1919 来源:http://sina.lt/getPMcGovernTheory在StackOverflow提了这样一个问题:Java虚拟机最多支持多少个线程?跟虚拟机开发商有关么?跟操作系统呢?还有其他的因素吗?Eddie的回答:这取决于你使用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 444,582
精华内容 177,832
关键字:

java线程数最大

java 订阅