`

NIO学习笔记——解决“服务器端cpu占用率高”

 
阅读更多
原文地址:http://blog.csdn.net/hepeng19861212/article/details/4479714


问题:服务器端启动后,cpu占用率很高,经常是99%,100%。
原因分析:RecvThread的终止判断条件最初是if (num == -1)//这里的num是指通道读取到buffer中的字节数,当没有数据时,客户端的IntputStream始终没有终止或关闭,
也就是说SocketChannel始终无法读到流的末尾。但是服务器的channel始终在尝试读取客户端的数据,但读取的数据都为空,
这样就使得cpu一直在做“无用功”——空转。

--------------------------------------------------
或许你会问,只不过才一个线程在接收数据而已,不至于使得cpu慢的如老牛耕地吧?你这样说是没错的。但是接下来,我在无意中做了个
小小的实验:我在RecvThread类中加入了运行时的debug信息。
另外,请观众注意,当我们在ListenThread中启动RecvThread并运行的同时,原先的线程ListenThread也没闲着,而是在继续往下执行。

服务器端启动后,我使用客户端发送了一个字符(仅仅是一个字符)给服务器端,意外出现了:服务器的console中打印了不止一个RecvThread线程的debug信息。
为什么会有这么多线程?按照我们的思路,当判断SelectionKey是readable厚,我们只new了一个线程来接收数据啊。而且NIO api中对

Selector的select()方法解释如下:

[java] view plaincopy

    public abstract int select() 
                        throws IOException 
    选择一组键,其相应的通道已为 I/O 操作准备就绪。  
    此方法执行处于阻塞模式的选择操作。仅在至少选择一个通道、调用此选择器的 wakeup 方法,或者当前的线程已中断(以先到者为准)后此方法才返回。  

是啊,没错啊,只有select至少一个有效的通道时,select()才会返回,否则就一直阻塞。
但是,从我刚才的实验中,大家也许很清楚的看到了,其实当RecvThread处理数据的同时,select()方法并没有阻塞,继而它后面的程序仍然会继续执行。
以至于new 了第二个、第三个....第n个RecvThread的实例。
后来我专门又输出了select()的返回值,结果也进一步验证了我刚才所言——RecvThread线程处理数据的同时,select()并没有老老实实的阻塞在那里,而是返回了一个0。

最后,唯一令我感到欣慰的是,这n个线程并不是每一个都接收了客户端发来的数据,而是仅仅其中一个线程接收到了数据。



解决方法:把RecvThread的终止判断条件改成if (num <= 0),并且强烈建议您:不要在selectionKey.isReadable()判断之后,去新建一个线程来接收到来的数据。原因1是因为刚才我所讲的一个消息对应n个线程,将耗费掉大量的cpu资源,
而且这n个线程中为我们做事的却只有其中一个(这也许刚好就是当今经济危机下大部分企业都在裁员的原因)。原因之二,千万不要单纯以为这不过是n个线程而已,
服务器接收客户端消息是很频繁的,一个消息对应n个线程,那么100条消息就对应了.....我想你不会希望看到自己的cpu被这n*100个线程累垮。^_^
分享到:
评论

相关推荐

    Java NIO学习笔记——ByteBuffer用法

    ByteBuffer的用法是Java NIO学习中的核心内容。 首先,我们了解下ByteBuffer的基本概念。ByteBuffer是一个字节缓冲区,可以存储字节序列。在NIO中,所有的数据读写都通过缓冲区进行,ByteBuffer与其他类型的Buffer...

    学习笔记——资料

    【Java学习笔记——全面解析】 Java作为一种广泛应用的高级编程语言,是软件开发领域的核心力量。这份"学习笔记——资料"涵盖了Java学习的各个方面,旨在帮助初学者和有经验的开发者巩固基础,提升技能。以下是对这...

    javaNIO学习笔记(csdn)————程序.pdf

    Java NIO,全称Non-Blocking Input/Output...NIO通过非阻塞的特性,结合选择器和事件驱动的机制,使得Java程序能够高效地处理大量并发的I/O操作,特别适合构建高性能的网络服务器,如Netty框架就充分利用了NIO的优势。

    Java JDK 6学习笔记——ppt简体版

    4. **NIO(非阻塞I/O)**:提高了网络编程的效率,尤其适用于高并发的服务器端应用。 5. **脚本语言支持**:引入JSR 223,使得Java平台可以直接支持JavaScript和其他脚本语言。 此外,学习笔记可能还会涉及一些实际...

    Java NIO——Java NIO

    Java NIO——Java NIO——Java NIO

    JDK 6学习笔记——PPT简体版

    **JDK 6学习笔记——PPT简体版** Java Development Kit(JDK)是Java编程语言的核心组件,它提供了开发和运行Java应用程序所需的工具和环境。JDK 6是Oracle公司发布的一个重要版本,为开发者带来了许多改进和新特性...

    nio demo for nio学习笔记(体系结构以及模块介绍)

    1. **高并发网络应用**:如服务器端处理大量客户端连接,NIO的非阻塞和多路复用特性非常合适。 2. **大文件传输**:在处理大文件时,直接内存访问可以减少数据拷贝,提高效率。 3. **低延迟需求**:对于需要快速响应...

    java jdk5.0学习笔记——良葛格

    良葛格的《Java JDK5.0学习笔记》是一本面向初学者的教程,旨在帮助读者掌握这个版本的核心概念和技术。以下是基于该书部分内容的知识点详解: 1. **泛型**:JDK 5.0引入了泛型,这是一种强大的类型系统增强,允许...

    使用Java_NIO编写高性能的服务器.doc

    ### 使用Java NIO编写高性能服务器的关键知识点 #### 一、NIO概述 - **NIO简介**:NIO(New IO)自JDK 1.4引入以来,为Java提供了非阻塞IO的支持,这对于提高服务端应用的性能至关重要。NIO的核心特性包括缓冲区...

    NIO学习笔记

    《NIO学习笔记》 在Java编程领域,NIO(Non-blocking Input/Output,非阻塞I/O)是一种重要的I/O模型,与传统的BIO(Blocking I/O)相对应。NIO提供了一种新的方式来处理I/O操作,特别是在处理大量并发连接时,它的...

    JAVA NIO学习笔记.docx

    NIO不仅提高了Java的I/O性能,还引入了非阻塞I/O模型,适合于开发高并发的服务器应用,比如网络服务器、数据库连接池等。通过NIO,开发者能够设计出更为灵活、高效的系统架构,充分利用硬件资源,提升系统吞吐量。

    java学习笔记1(java io/nio)

    java学习笔记1(java io/nio)设计模式

    java nio Selector的使用-服务器端

    Java NIO(New IO)是Java 1.4版本引入的一个新模块,它提供了一种新的方式来处理I/O操作,相比传统的IO模型,NIO提供了更高效、更灵活的I/O编程。Selector是Java NIO中的核心组件,用于监听多个通道的事件,如连接...

    大数据学习之旅——NIO源码

    对于大数据处理,NIO的一个典型应用场景是高并发的网络服务器,例如基于NIO的Tomcat服务器。服务器可以使用一个线程来处理多个客户端连接,通过选择器监控所有连接的状态,当有数据到来时,才进行实际的读写操作,...

Global site tag (gtag.js) - Google Analytics