多线程并发导致CPU100%的一种原因和解决办法

您所在的位置:网站首页 原神cpu占用率高怎么办解决方法 多线程并发导致CPU100%的一种原因和解决办法

多线程并发导致CPU100%的一种原因和解决办法

2024-07-12 21:04| 来源: 网络整理| 查看: 265

在用自定义线程池的时候,遇到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就不会升到100 private 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回收。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3