• 关于线程池newFixedThreadPool使用注意事项


    使用线程池的目的是希望线程控制在某个范围内,以免造成服务崩溃,所以在使用线程池的时候要多加注意。

    记录原因:一个webservice中转项目,需求很简单,提供webservice接口接收数据,然后入库,再通过webservice将数据原样推送给其他应用,推送数据给应用时使用的是线程池,保证一定的并发量处理代码如下:

     1 @Component
     2 public class WebServiceClient {
     3     private Logger logger = Logger.getLogger(this.getClass());
     4     private Configuration config = Configuration.getInstance();
     5     private ExecutorService executors = Executors.newFixedThreadPool(20);
     6 
     7     @Autowired
     8     private ZkMessagePushFailedService zkMessagePushFailedService;
     9     /**
    10      * webservice推送
    11      * @param list
    12      */
    13     public void webServicePush(List<byte[]> list){
    14         if (null != list && !list.isEmpty()){
    15             for (int i = 0; i < list.size(); i++) {
    16                 executors.execute(new Call((String) SerializeUtils.unserialize(list.get(i))));
    17             }
    18         }
    19     }
    20 
    21     class Call implements Runnable{
    22         String content;
    23 
    24         public Call(String content){
    25             this.content = content;
    26         }
    27 
    28         @Override
    29         public void run() {
    30             //省略业务代码
    31 
    32             logger.info("webservice exec end-------------------");
    33         }
    34     }
    35 }

    在外部通过

    1 WebServiceClient client = new WebServiceClient();
    2 client.webServicePush(list);

    来调用webServicePush方法,乍一看没什么问题,实际上问题很大。

    项目上线几天后,通过SSH就登录不上服务器了(阿里云服务器),但是页面能访问,只是没有任何数据,通过阿里云平台远程登录功能登录后登录不上,报以下错误:

    --root:fork failed:Cannot allocate memory

    刚开始还以为服务器被攻击了,百度查了一下,说是线程数达到系统的最大线程数造成的,重启阿里云服务器,启动tomcat和相关应用,通过linux命令ps -eLf | wc -l来查看进程及线程情况,发现tomcat进程下在不断的增加线程,只增不减,最终导致以上问题。

    通过一系列的排除法,发现就是线程池使用不当导致的,原因就在于我是用new的方式来创建对象的WebServiceClient client = new WebServiceClient(),而这个对象里有个线程池,就相当于每次创建一个对象的同时就创建了一个线程池,导致tomcat线程不断的增加。

    解决方法:

    1、将线程池声明为静态的

    private final static ExecutorService executors = Executors.newFixedThreadPool(20);

    2、将WebServiceClient类做成单例的

    自此该问题得到解决,粗心导致的,记录一下。
    ————————————————
    版权声明:本文为CSDN博主「ganchunsaixx」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/ganchunsaixx/java/article/details/100016408

  • 相关阅读:
    C#开发微信门户及应用(30)--消息的群发处理和预览功能
    C#开发微信门户及应用(30)--消息的群发处理和预览功能
    C#开发微信门户及应用(30)--消息的群发处理和预览功能
    ssh密码登陆的原理,密码的公私钥和sshkey的不是一回事
    ssh密码登陆的原理,密码的公私钥和sshkey的不是一回事
    ssh密码登陆的原理,密码的公私钥和sshkey的不是一回事
    ssh密码登陆的原理,密码的公私钥和sshkey的不是一回事
    原生JS设计轮播图
    C#从SQL server数据库中读取l图片和存入图片
    C#从SQL server数据库中读取l图片和存入图片
  • 原文地址:https://www.cnblogs.com/it-deepinmind/p/13072184.html
Copyright © 2020-2023  润新知