zoukankan      html  css  js  c++  java
  • JAVA线程池资源回收的问题

    最近项目中为了提高用户体验度,前台创建任务后台任务,用多线程来跑。

    现在的场景:后台定时任务管理这两个线程池,一个最大线程数10个,一个最大线程数15。应用部署之后,不超过5个小时,服务器负载高,内存使用过多。

    分析原因:因为这个功能是excel导入功能,如果前台有大量的导入任务时,那么后台的负载就会很高。

         我的实现原理:定时任务读取任务,放到任务队列表中,然后使用线程池消费任务队列中的任务,每个线程时一直循环取任务。

         我的定时任务周期是 1 分钟,线程池从初始化时,空闲线程存活的时间为 1 分钟,任务队列没有设定最大数量值。

    优化:  

      1.任务队列没有上限

        定时任务每次启动都回去数据库中读取任务,放入对列表中,如果一直往任务队列中放,那么任务队列占用的内存会越来越大,导致服务器内存不足。

       解决办法:定时任务在读取任务时,先判断任务队列的大小,比如我这设置的100个,那么我就不再读取新的任务了。这个参数需要通过观察机器的负载,然后来调整。

      2.线程池中的线程,无限循环处理任务,当任务数量过多的时候,线程会一直执行,停不下来。

        线程池中的线程,无限循环处理任务,当任务数量过多的时候,线程会一直执行,停不下来。

       解决办法:在线程内部设置计数器,当一个线程累计到一定数量,退出循环,然后清空资源,回收,间歇性,周期的执行任务,相当于定期回收资源

      3.定时任务 1 分钟,那么空闲线程存活的时间为1分钟

        由于空闲线程存活时间是 1 分钟,那么我的定时任务也是 1 分钟,这个时候,线程就基本就不会被线程池回收,那么资源就一直没有释放,被回收。

       解决办法:调整线程空闲的线程存活时间为定时任务周期的一半,也就是30秒。

      4.在线程池中,有核心线程,对于核心线程超时也回收,所以,需要执行下边这个方法,确保核心线程超时之后也被回收。

       解决办法:threadPoolExecutor.allowCoreThreadTimeOut(true);

    优化之后的流程

      任务定期读取任务,往任务队列中放一定量(不能超过最大值)的任务,之后线程池中的线程超时时间设置短一点,线程通过计数器,当执行了一定数量的线程之后,推出循环,这个时候线程就空闲了,后边就会被线程池回收,资源被回收,如此反复进行下去,资源回收,重新分配,不会大量消耗服务资源。

      通过以上几个点的优化,程序消耗服务器资源好很多,可能还有优化的地方,后边再补充。

    Read the fucking manual and source code
  • 相关阅读:
    Luogu 4841 城市规划
    Luogu 4721 【模板】分治 FFT
    Luogu 4091 [HEOI2016/TJOI2016]求和
    Luogu 3723 [AH2017/HNOI2017]礼物
    FFT笔记
    Luogu 4900 食堂
    Luogu 4155 [SCOI2015]国旗计划
    Luogu 4069 [SDOI2016]游戏
    Luogu 4254 [JSOI2008]Blue Mary开公司
    Luogu 4251 [SCOI2015]小凸玩矩阵
  • 原文地址:https://www.cnblogs.com/qxynotebook/p/7398882.html
Copyright © 2011-2022 走看看