博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程并发导致CPU100%的一种原因和解决办法
阅读量:6588 次
发布时间:2019-06-24

本文共 2118 字,大约阅读时间需要 7 分钟。

在用自定义线程池的时候,遇到cpu100%,经过验证后,发现问题来源于我定义的子线程。 

子线程的主要功能是从任务队列(LinkedBlockingQueue)里面持续拿出任务,并且执行。 
以下为令CPU100的代码。

private  class WorkThread extends Thread    {        @Override        public void run()        {            while(flag)            {                       Runnable task=null;                if(flag&&!taskQueue.isEmpty())//当队列非空                {                    try                     {                        task=taskQueue.poll();//拿到任务,若没有则拿到null                        if(task!=null)                            task.run();//执行任务                    } catch (Exception e)                     {                        e.printStackTrace();                    }                }               }        }           }

之后,随便往while循环里面添加进System.out.println(“xxxx”); 

发现CPU降低了,不会升到100,于是我修改了代码如下:

//增加一句Thread.sleep(),令所有线程每次进入while循环的时候,都先休眠释放资源,这CPU就不会升到100private  class WorkThread extends Thread    {        @Override        public void run()        {            while(flag)            {                try {                    Thread.sleep((long) 0.5);//先释放资源,避免cpu占用过高                } catch (Exception e1) {                    // TODO Auto-generated catch block                    e1.printStackTrace();                }                Runnable task=null;                if(flag&&!taskQueue.isEmpty())//当队列非空                {                    try                     {                        task=taskQueue.poll();//拿到任务,若没有则拿到null                        if(task!=null)                            task.run();//执行任务                    } catch (Exception e)                     {                        e.printStackTrace();                    }                }               }        }           }

造成上述现象的原因:LinkedBlockingQueue是线程安全,当多线程同步从队列里面取出任务,在微观时刻,有且只有一个线程能进入队列中取,因此其他线程阻塞等待,此时各线程都持有cpu资源,不释放, 

就造成了大量cpu等待,因而CPU会升高; 
值得注意的一点: 
LinkedBlockingQueue中取出任务方法有几种,比如take(),poll(),一开始我用take方法,发现运行后,线程资源无法得到释放,后来看了api发现take()是阻塞拿,意思是:线程往队列里面拿任务, 
如果队列里面没有任务,则进行等待知道有任务再次唤醒。 
而poll()方法则是有任务就拿,没任务就返回null,因此不会出现阻塞等待,若上面代码改成用take方法,同样会出现cpu100的问题,也在于阻塞,同时也会出现线程不被GC回收。

转载于:https://my.oschina.net/vshcxl/blog/744717

你可能感兴趣的文章
memcache 源码分析之开场白
查看>>
javaweb学习总结(六)——Servlet开发(二)
查看>>
ectouch手机商城首页调用指定分类下的商品
查看>>
软件测试有前途吗
查看>>
OC高效率52之“方法调配技术”调试“黑盒方法”
查看>>
Vue学习笔记01
查看>>
概念性问题
查看>>
Categories
查看>>
如何为CentOS 7配置静态IP地址
查看>>
c:递归算法的三个demo:八皇后问题、台阶问题、汉诺塔
查看>>
Linux-dns基础知识和BIND的简单配置-3(主从DNS服务器及转发)
查看>>
Linux 管道(pipe)原理及使用
查看>>
基于Nginx的Wesocket负载均衡
查看>>
python 函数
查看>>
OAuth2.0介绍
查看>>
"No space left on device" 磁盘空间提示不足解决办法
查看>>
leetcode题解—1021、删除最外层的括号
查看>>
redis主从和持久化
查看>>
【Windows编程】系列第六篇:创建Toolbar与Statusbar
查看>>
Linux篇 | 磁盘存储和文件系统
查看>>