Java NIO原理图文分析及代码实现
前言:
最近在分析hadoop的RPC(Remote Procedure Call Protocol ,远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。可以参考:http://baike.baidu.com/view/32726.htm )机制时,发现hadoop的RPC机制的实现主要用到了两个技术:动态代理(动态代理可以参考博客:http://weixiaolu.iteye.com/blog/1477774 )和java NIO。为了能够正确地分析hadoop的RPC源码,我觉得很有必要先研究一下java NIO的原理和具体实现。
这篇博客我主要从两个方向来分析java NIO
目录:
一.java NIO 和阻塞I/O的区别
1. 阻塞I/O通信模型
2. java NIO原理及通信模型
二.java NIO服务端和客户端代码实现
具体分析:
一.java NIO 和阻塞I/O的区别
1. 阻塞I/O通信模型
假如现在你对阻塞I/O已有了一定了解,我们知道阻塞I/O在调用InputStream.read()方法时是阻塞的,它会一直等到数据到来时(或超时)才会返回;同样,在调用ServerSocket.accept()方法时,也会一直阻塞到有客户端连接才会返回,每个客户端连接过来后,服务端都会启动一个线程去处理该客户端的请求。阻塞I/O的通信模型示意图如下:
如果你细细分析,一定会发现阻塞I/O存在一些缺点。根据阻塞I/O通信模型,我总结了它的两点缺点:
1. 当客户端多时,会创建大量的处理线程。且每个线程都要占用栈空间和一些CPU时间
2. 阻塞可能带来频繁的上下文切换,且大部分上下文切换可能是无意义的。
在这种情况下非阻塞式I/O就有了它的应用前景。
2. java NIO原理及通信模型
Java NIO是在jdk1.4开始使用的,它既可以说成“新I/O”,也可以说成非阻塞式I/O。下面是java NIO的工作原理:
1. 由一个专门的线程来处理所有的 IO 事件,并负责分发。
2. 事件驱动机制:事件到的时候触发,而不是同步的去监视事件。
3. 线程通讯:线程之间通过 wait,notify 等方式通讯。保证每次上下文切换都是有意义的。减少无谓的线程切换。
阅读过一些资料之后,下面贴出我理解的java NIO的工作原理图:
(注:每个线程的处理流程大概都是读取数据、解码、计算处理、编码、发送响应。)
Java NIO的服务端只需启动一个专门的线程来处理所有的 IO 事件,这种通信模型是怎么实现的呢?呵呵,我们一起来探究它的奥秘吧。java NIO采用了双向通道(channel)进行数据传输,而不是单向的流(stream),在通道上可以注册我们感兴趣的事件。一共有以下四种事件:
事件名
对应值
服务端接收客户端连接事件
SelectionKey.OP_ACCEPT(16)
动力节点Java301集基础客户端连接服务端事件
SelectionKey.OP_CONNECT(8)
读事件
SelectionKey.OP_READ(1)
写事件
SelectionKey.OP_WRITE(4)
/colgroup>
tbody>
/tbody>
二.java NIO服务端和客户端代码实现
/strong>
br>
br> 为了更好地理解java NIO,下面贴出服务端和客户端的简单代码实现。
br>
br>
服务端:
Java代码
br>
package
/strong> cn.nio;
import
/strong> java.io.IOException;
import
/strong> java.net.InetSocketAddress;
import
/strong> java.nio.ByteBuffer;
import
/strong> java.nio.channels.SelectionKey;
import
/strong> java.nio.channels.Selector;
import
/strong> java.nio.channels.ServerSocketChannel;
import
/strong> java.nio.channels.SocketChannel;
import
/strong> java.util.Iterator;
public class
/strong> NIOServer {
private
/strong> Selector selector;
public void
/strong> initServer(
int
/strong> port)
throws
/strong> IOException {
false
/strong>);
new
/strong> InetSocketAddress(port));
this
/strong>.selector = Selector.open();
public void
/strong> listen()
throws
/strong> IOException {
while
/strong> (
true
/strong>) {
this
/strong>.selector.selectedKeys().iterator();
while
/strong> (ite.hasNext()) {
if
/strong> (key.isAcceptable()) {
false
/strong>);
new
/strong> String("向客户端发送了一条信息").getBytes()));
this
/strong>.selector, SelectionKey.OP_READ);
else if
/strong> (key.isReadable()) {
public void
/strong> read(SelectionKey key)
throws
/strong> IOException{
byte
/strong>[] data = buffer.array();
new
/strong> String(data).trim();
public static void
/strong> main(String[] args)
throws
/strong> IOException {
new
/strong> NIOServer();
br>
客户端:
Java代码
br>
package
/strong> cn.nio;
import
/strong> java.io.IOException;
import
/strong> java.net.InetSocketAddress;
import
/strong> java.nio.ByteBuffer;
import
/strong> java.nio.channels.SelectionKey;
import
/strong> java.nio.channels.Selector;
import
/strong> java.nio.channels.SocketChannel;
import
/strong> java.util.Iterator;
public class
/strong> NIOClient {
private
/strong> Selector selector;
public void
/strong> initClient(String ip,
int
/strong> port)
throws
/strong> IOException {
false
/strong>);
this
/strong>.selector = Selector.open();
new
/strong> InetSocketAddress(ip,port));
public void
/strong> listen()
throws
/strong> IOException {
while
/strong> (
true
/strong>) {
this
/strong>.selector.selectedKeys().iterator();
while
/strong> (ite.hasNext()) {
if
/strong> (key.isConnectable()) {
if
/strong>(channel.isConnectionPending()){
false
/strong>);
new
/strong> String("向服务端发送了一条信息").getBytes()));
this
/strong>.selector, SelectionKey.OP_READ);
else if
/strong> (key.isReadable()) {
public void
/strong> read(SelectionKey key)
throws
/strong> IOException{
public static void
/strong> main(String[] args)
throws
/strong> IOException {
new
/strong> NIOClient();
br>
小结:
/strong>
br>
br> 终于把动态代理和java NIO分析完了,呵呵,下面就要分析hadoop的RPC机制源码了,博客地址:http://weixiaolu.iteye.com/blog/ 。不过如果对java NIO的理解存在异议的,欢迎一起讨论。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/24998.html