• java 线程池场景


    java 一共含有四种线程池: newCachedThreadPool, newFixedThreadPool, newSingleThreadExecutor, newScheduledThreadPool。

    newCachedThreadPool:顾名思义是一种可缓存的线程池, 线程池除了维护初始大小的线程外,当任务数量超出线程池大小时,便会新建线程, 而且当线程完成任务之后不会马上销毁,而是会保留一段时间(默认60s),这种极大的减少了线程创建和销毁的资源消耗, 当这种线程池的弊端是 线程最大值过大, 如果用于高并发且任务较长场景,很容易将内存全部吃光。 所以使用于执行短期异步小任务,或者并发量不高的场景。

    newFixedThreadPool :是基于无界队列的线程池, 维护的线程数量是固定的,如果线程均在繁忙状态,则新任务会放入无界队列里。 适用于长期任务。 如果用于短期任务,任务数量 < 线程池数量时,性能不会跟newCachedThreadPool太大的区别,但是超出时, 因为是短期的, 所以任务会不断的被放入队列,又被取出, 时间间隔很短,并且过多的短期任务放入队列中,回使得内存吃紧,当任务数量过多时会造成很大的资源浪费。

    newSingleThreadExecutor:顾名思义是只有一个单线程的线程池,具体场景不太清晰, 按照线程含义来看,适用于需要按顺序(FIFO, LIFO, 优先级)的执行任务的场景,以及thread confinement(变量只能由特定线程访问)的要求。

    newScheduleThreadPool :如果所有线程均处于繁忙状态,对于新任务会进入DelayedWorkQueue队列中,这是一种按照超时时间排序的队列结构。这个线程的应用场景就很容易知道了, 需要周期性执行的任务使用该线程池。

    线程池任务执行流程:

      当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
      当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
      当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务
      当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
      当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
      当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭
    备注:

    一般如果线程池任务队列采用LinkedBlockingQueue队列的话,那么不会拒绝任何任务(因为队列大小没有限制),这种情况下,ThreadPoolExecutor最多仅会按照最小线程数来创建线程,也就是说线程池大小被忽略了。

    如果线程池任务队列采用ArrayBlockingQueue队列的话,那么ThreadPoolExecutor将会采取一个非常负责的算法,比如假定线程池的最小线程数为4,最大为8所用的ArrayBlockingQueue最大为10。随着任务到达并被放到队列中,线程池中最多运行4个线程(即最小线程数)。即使队列完全填满,也就是说有10个处于等待状态的任务,ThreadPoolExecutor也只会利用4个线程。如果队列已满,而又有新任务进来,此时才会启动一个新线程,这里不会因为队列已满而拒接该任务,相反会启动一个新线程。新线程会运行队列中的第一个任务,为新来的任务腾出空间。

    这个算法背后的理念是:该池大部分时间仅使用核心线程(4个),即使有适量的任务在队列中等待运行。这时线程池就可以用作节流阀。如果挤压的请求变得非常多,这时该池就会尝试运行更多的线程来清理;这时第二个节流阀—最大线程数就起作用了。

    ThreadPoolExecutor:

      private static int runStateOf(int c) { return c & ~CAPACITY; }    
      private static int workerCountOf(int c) { return c & CAPACITY; }   //因为ctl以(1<<29)开始递增,转化为以0开始递增的数字  例如 workerCOuntOf( (1<<29) +9 ) = 9;
      private static int ctlOf(int rs, int wc) { return rs | wc; }

    参考文章:https://www.cnblogs.com/sachen/p/7401959.html

  • 相关阅读:
    LVS-三种负载均衡方式比较
    keepalived和heartbeat区别
    vmware-question
    SQL Server MYSQL 检查点的好处
    MYSQL 引擎的情况
    MYSQL 关闭服务的过程
    SQL Server 行的删除与修改-------------(未完待续P222 deep SQL Server 222 )
    SQL Server一些重要视图 1
    SQL Server 查看数据页面
    SQL Server 向堆表中插入数据的过程
  • 原文地址:https://www.cnblogs.com/yuanshixingdan/p/8320283.html
Copyright © 2020-2023  润新知