java用while循环设计轮询线程的性能问题
来源:互联网 发布:抄袭检测软件 编辑:程序博客网 时间:2024/06/06 11:48
java用while循环设计轮询线程的性能问题
轮询线程在开发过程中的应用是比较广泛的,在这我模拟一个场景,有一个队列和轮询线程,主线程往队列中入队消息,轮询线程循环从队列中读取消息并打印消息内容。有点类似Android中Handler发送消息。
首先定义一个Message类。
public class Message { private String content; public Message(String content) { this.content=content; } public void display(){ System.out.println(content); }}
这个类很简单,在构造的时候传入消息内容,display()方法输出打印消息内容。
接下来定义一个轮询线程,一开始蠢萌的我这么写
public class PollingThread extends Thread implements Runnable { public static Queue<Message> queue = new LinkedTransferQueue<Message>(); @Override public void run() { while (true) { while (!queue.isEmpty()) { queue.poll().display(); } } }}
这个轮询线程功能很简单,一直不停的轮询队列,一旦队列中有消息进入,就将它出队并调用display()方法输出内容。
接下来在Main()方法中循环创建消息将它放入队列
public class Main { public static void main(String[] args){ PollingThread pollingThread=new PollingThread(); pollingThread.start(); int i=1; while(true) { PollingThread.queue.offer(new Message("新消息"+i)); i++; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } }}
运行结果
新消息1新消息2新消息3新消息4新消息5新消息6新消息7新消息8新消息9新消息10新消息11新消息12新消息13新消息14新消息15......
虽然这么做,功能是实现了,可是我们来看下cpu占用率
程序刚编译启动的时候cpu占用率到了100%,开始运行后一直处于44%左右。这个占用率还是比较高的,那么我们来分析一下这个轮询线程,假设一直没有消息入队,或者消息入队的间隔时间比较长的话,它就会循环的去执行while(!queue.isEmpty())判断队列是否为空,其实这个判断操作是非常耗性能的。我们应该把这个轮询线程设计的更合理一点。那么怎样设计比较合理呢?既然循环对队列判空是比较浪费性能的操作,那么我们如果可以让这个轮询线一开始处于阻塞状态,主线程在每次入队消息的时候通知轮询线程循环出队输出消息内容,当队列为空的时候轮询线程又自动的进入阻塞状态,就可以避免轮询线程死循环对队列判空。接下来我们改造一下轮询线程和主线程的代码
public class PollingThread extends Thread implements Runnable { public static Queue<Message> queue = new LinkedTransferQueue<Message>(); @Override public void run() { while (true) { while (!queue.isEmpty()) { queue.poll().display(); } //把队列中的消息全部打印完之后让线程阻塞 synchronized (Lock.class) { try { Lock.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }}
public class Main { public static void main(String[] args){ PollingThread pollingThread=new PollingThread(); pollingThread.start(); int i=1; while(true) { PollingThread.queue.offer(new Message("新消息"+i)); i++; //有消息入队后激活轮询线程 synchronized (Lock.class) { Lock.class.notify(); } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } }}
这时候再来运行一下
运行结果
新消息1新消息2新消息3新消息4新消息5新消息6新消息7新消息8新消息9新消息10新消息11......
再来看看cpu占用率
轮询线程经过改造后cpu占用率基本稳定在11%,比之前44%下降了不少。
所以,在编写轮询线程的时候,尽量用通知的方式去让轮询线程执行操作,避免重复的条件判断造成的性能浪费。
0 0
- java用while循环设计轮询线程的性能问题
- java/C.C++线程while循环无法跳出问题分析
- 用线程终止while循环
- java -- while循环拆分性能测试程序
- Java的while、for循环
- JAVA 的 while 循环语句
- java for/foreach/while 3种循环性能比较
- 关于do while循环的问题
- 关于do while循环的问题
- for 循环嵌套 while 的神奇问题
- Html5 Websocket while死循环的问题
- 一个易错的while循环问题
- java 用 for do...while 和 while循环求1到100之间的偶数和
- java中循环命令while,for,do while的区别
- JAVA 的 do-while 循环语句
- shell while循环问题
- 【java基础】解决Java中 while(Scanner.hasNext())一直为死循环的问题!
- JAVA-while循环语句
- Android触摸事件派发机制源码分析之ViewGroup
- Java 7之多线程并发容器
- 简单理解js的prototype属性
- 微信小程序入门教程+案例demo
- Java小程序-猜数字程序(只能玩有限次)
- java用while循环设计轮询线程的性能问题
- AppBarLayout滑动原理
- 频数相关的leetcode:451 Sort Characters By Frequency& 347 Top K Frequent Elements
- Anker—工作学习笔记
- vim 自动添加头注释
- 编译器自动优化——为什么我的C++编译器不调用拷贝构造函数了?
- 字符串复制strcpy()实现及常见问题
- Qt 在mac 下添加第三方 framework的方法
- 简单的fastboot命令: