原文:
NIO的使用http://hi.baidu.com/zbzb/blog/item/ba775eee89e2b2fbb3fb9515.html
使用Java NIO编写高性能的服务器http://www.iteye.com/post/192013
一. 介绍NIO
NIO包(java.nio.*)引入了四个关键的抽象数据类型,它们共同解决传统的I/O类中的一些问题。
1. Buffer:它是包含数据且用于读写的线形表结构。其中还提供了一个特殊类用于内存映射文件的I/O操作。
2. Charset:它提供Unicode字符串影射到字节序列以及逆影射的操作。
3. Channels:包含socket,file和pipe三种管道,它实际上是双向交流的通道。
4. Selector:它将多元异步I/O操作集中到一个或多个线程中(它可以被看成是Unix中select()函数或Win32中WaitForSingleEvent()函数的面向对象版本)。
二. 回顾传统
在介绍NIO之前,有必要了解传统的I/O操作的方式。以网络应用为例,传统方式需要监听一个ServerSocket,接受请求的
连接为其提供服务(服务通常包括了处理请求并发送响应)。
可以分析创建服务器的每个具体步骤。
首先创建ServerSocket
ServerSocket server=new ServerSocket(10000);
然后接受新的连接请求
Socket newConnection=server.accept();
对于accept方法的调用将造成阻塞,直到ServerSocket接受到一个连接请求为止。一旦连接请求被接受,
服务器可以读客户socket中的请求。
InputStream in = newConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
BufferedReader buffer = new BufferedReader(reader);
Request request = new Request();
while(!request.isComplete()) {
String line = buffer.readLine();
request.addLine(line);
}
这样的操作有两个问题,首先BufferedReader类的readLine()方法在其缓冲区未满时会造成线程阻塞,只有一定数据填满了
缓冲区或者客户关闭了套接字,方法才会返回。其次,它回产生大量的垃圾,BufferedReader创建了缓冲区来从客户套接字读入数据,但是同样创建了一些字符串存储这些数据。虽然BufferedReader内部提供了StringBuffer处理这一问题,但是所有的String
很快变成了垃圾需要回收。同样的问题在发送响应代码中也存在
Response response = request.generateResponse();
OutputStream out = newConnection.getOutputStream();
InputStream in = response.getInputStream();
int ch;
while(-1 != (ch = in.read())) {
out.write(ch);
}
newConnection.close();
类似的,读写操作被阻塞而且向流中一次写入一个字符会造成效率低下,所以应该使用缓冲区,但是一旦使用缓冲,流又会产生更多的垃圾。
传统的解决方法通常在Java中处理阻塞I/O要用到线程(大量的线程)。一般是实现一个线程池用来处理请求。线程使得服务器可以处理多个连接,但是它们也同样引发了许多问题。每个线程拥有自己的栈空间并且占用一些CPU时间,耗费很大,而且很多时间是浪费在阻塞的I/O操作上,没有有效的利用CPU。
三.NIO的反应器模式
NIO服务器最核心的一点就是反应器模式:当有感兴趣的事件发生的,就通知对应的事件处理器去处理这个事件,如果没有,则不处理。所以使用一个线程做轮询就可以了。当然这里这是个例子,如果要获得更高性能,可以使用少量的线程,一个负责接收请求,其他的负责处理请求,特别是对于多CPU时效率会更高。
//注册事件
client.register(selector, SelectionKey.OP_CONNECT);
channel.register(selector, SelectionKey.OP_READ);
//实现Selector监听的永真循环,判断事件
if (key.isConnectable()) {do your work}
if (key.isReadable()) {do your work}
关于使用NIO过程中出现的问题,最为普遍的就是为什么没有请求时CPU的占用率为100%?
出现这种问题的主要原因是注册了不感兴趣的事件,比如如果没有数据要发到客户端,而又注册了写事件(OP_WRITE),则在 Selector.select()上就会始终有事件出现,CPU就一直处理了,而此时select()应该是阻塞的。
另外一个值得注意的问题是:由于只使用了一个线程(多个线程也如此)处理用户请求,所以要避免线程被阻塞,解决方法是事件的处理者必须要即刻返回,不能陷入循环中,否则会影响其他用户的请求速度。
分享到:
相关推荐
接着是NIO,非阻塞I/O。NIO在Java 1.4引入,其核心在于Channel和Buffer。与BIO不同,NIO允许单个线程服务多个客户端,通过Selector进行轮询检查,当数据准备好读取或写入时才进行实际操作,从而提高了系统资源利用率...
在面试中,了解和掌握这些知识点对于成为一名合格的Java开发者至关重要。 首先,Java的IO流体系是其核心特性之一。IO流可以分为四种基本类型:输入流(InputStream/Reader)、输出流(OutputStream/Writer)、字节...
- **AIO (Asynchronous I/O)**:也称为NIO.2,异步非阻塞I/O,由操作系统负责I/O操作的完成通知,服务器端只需要处理真正的业务逻辑,无需等待I/O完成。 ### 2. NIO 的组成 - **Buffer**:数据交互的核心,数据从...
2. NIO(New I/O):同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生...
Java I/O和NIO(非阻塞I/O)也是面试常客。理解流的概念,以及不同类型的流(字节流和字符流)和它们的关联类,比如FileInputStream和FileOutputStream。NIO的引入提供了更高的I/O效率,面试中可能会讨论通道、缓冲...
- NIO(New IO):了解缓冲区、选择器和非阻塞I/O。 9. **网络编程** - Socket编程:客户端和服务端的建立连接,数据传输。 - URL和URLConnection:用于网络资源的访问。 10. **设计模式** - 常见的设计模式:...
Java是目前广泛使用的编程语言之一,它在面试中的核心知识点主要集中在Java语言基础、集合框架、JVM内存模型、垃圾回收机制和Java I/O/NIO模型等方面。 首先,Java内存模型是Java虚拟机(JVM)运行Java程序时的内存...
7. **IO/NIO/BIO**:输入输出流体系结构,缓冲区,转换流,以及Java NIO(非阻塞I/O)的优势和使用场景。 8. **反射机制**:Java反射允许在运行时检查类、接口、字段和方法的信息,甚至动态创建对象和调用方法。...
- NIO(非阻塞I/O):选择器、通道、缓冲区的概念,以及其相对于传统IO的优势。 5. **反射与注解**: - 反射机制:动态获取类信息,创建对象,调用方法,修改属性,以及反射在设计模式中的应用。 - 注解:元数据...
- **四种模型**: 阻塞I/O、非阻塞I/O、多路复用I/O(如NIO中的Selector机制)、异步I/O。 - **NIO (New IO)**: - `Selector`: 用于监听多个通道的就绪状态。 - `Channel`: 数据传输的通道。 - `Buffer`: 数据...
事件驱动模型、单线程处理多任务、非阻塞 I/O,I/O 读写不再阻塞,而是返回0、基于 block 的传输比基于流的传输更高效、更高级的 IO 函数 zero-copy、IO 多路复用大大提高了 Java 网络应用的可伸缩性和实用性。...
- **NIO (Non-blocking I/O)**:非阻塞I/O模型,基于Java NIO API,使用一个线程可以处理多个连接,通过多路复用器(如Java的Selector)监控连接,当连接上有I/O事件发生时才进行处理,减少了线程开销。 - **AIO ...
AIO(NIO.2)是异步非阻塞I/O,操作系统负责完成I/O操作,然后通知应用程序,适合处理大量连接且操作较重的情况。 【IOC(Inversion of Control)】 IOC是控制反转的概念,Spring框架通过工厂模式和反射机制实现。...
- **NIO (Non-blocking I/O)**: Netty是基于Java NIO构建的,NIO是一种非阻塞I/O模型,能够处理大量并发连接。 - **Channel**: Netty中的核心概念,代表一个I/O连接,可以读写数据。 - **EventLoop**: 负责处理I/...
NIO(Non-Blocking I/O)是一种非阻塞的 I/O 模式,使用多路复用器轮询连接请求,客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有 I/O 请求时才启动一个线程进行处理。AIO(Asynchronous I/O)...
传统的I/O是阻塞式IO模型,而NIO提供了非阻塞式IO模型、多路复用IO模型、信号驱动IO模型和异步IO模型等。Java NIO核心组件包括通道(Channel)、缓冲区(Buffer)、选择器(Selector)等,这些组件是实现高效、可...
此外,NIO(非阻塞I/O)和AIO(异步I/O)也是现代Java开发中的重要知识点。 数据库操作是大多数互联网应用的基础,因此SQL语句的编写和优化、事务管理、索引原理、数据库设计原则等内容也是面试中不可或缺的部分。...
Netty基于NIO(非阻塞I/O)模型,它提供了高度抽象的API,简化了网络编程。在Netty中,I/O操作被封装在Channel接口中,而ChannelHandler则用于处理I/O事件和数据。事件循环(EventLoop)是Netty处理事件的关键组件,...
- NIO(非阻塞I/O):缓冲区、选择器、通道的概念及其实现异步I/O的优势。 - BIO(阻塞I/O):传统I/O模型的使用及局限性。 7. **反射** - 反射机制:如何通过反射创建对象、调用方法、访问字段。 - 动态代理:...