大数据基础(一):Java NIO概述及简单示例

本文介绍了Java NIO的基本概念和核心组件,包括Buffer、Channel和Selector。对比了NIO与传统IO的区别,强调了NIO的非阻塞特性。并提供了NIO在服务器回显实例中的应用,展示了如何利用Selector处理多个连接请求。
摘要由CSDN通过智能技术生成

1. IO与NIO的区别:为什么需要NIO?

1.1 java IO中的socket连接

在最初的java版本中,对于接受socket连接的服务器,其基本的处理步骤是:

1、实例化一个ServerSocket对象;
2、将实例化后的Serversocket对象绑定到某个端口上;
3、使用accept( )方法监听通过此端口的socket连接,这是accept( )方法会一直阻塞直到有连接进入;
4、收到socket连接之后,accept( )方法返回一个Socket对象,与客户端建立连接进行通信;
5、等待客户端或者服务器断开连接,返回到第3步等待下一次的连接。

下图截自《Hadoop技术内幕:深入理解Hadoop Common和HDFS架构设计与实现原理》,表示最初的客户端与服务器端的连接。

这里写图片描述

在 java 最初的 IO 中,OutputStream和InputStream没有提供异步的的IO读写,并且服务器端的accept( ) 方法是阻塞的。这意味着在客户端中需要采用一个线程对应一个客户端连接的策略来保证服务器可以同时接受来自多个客户端的连接。这就会导致大量的系统开销和负担。这种阻塞的通信模式也正是NIO所要解决的主要问题!

1.2. NIO与IO的区别
NIO IO
非阻塞 阻塞
面向缓冲(buffer) 面向流(stream)
有选择器 无选择器

2. NIO的三个主要组件

NIO实现的一个重要的功能就是非阻塞的通信,为此NIO引入了Selector(选择器)和Channel(通道)的概念,并且使用新的抽象结构:Buffer(缓冲区)来达到更高读写效率。

2.1 Buffer

Buffer是一个有固定容量的容器,其本质是一块被包装成了java对象的内存,并且提供一些方法操纵和访问这块内存。Buffer有读模式和写模式两种模式。Buffer类及其子类的类实现关系如下;

这里写图片描述

2.1.1 Buffer的四个主要概念

这里写图片描述

上图为jdk1.8 中java.nio.Buffer.java 中的部分源码,可以看到在Buffer源码的开始部分,定义了四个变量:

  • capacity: buffer 的容量,一旦一个buffer被创建完成,它的capacity的值就不可被修改;
  • limit: buffer区域中第一个不能被读取或者写入的位置,可以使用java.nio.Buffer中的public final Buffer limit(int newLimit)方法自定义limit的位置。在读模式下limit表示可以读取到多少的数据,在写模式下limit与capacity的值保持一致,当buffer由写模式切换到读模式的时候,limit值会由capacity的值切换为写模式下的position的值;
  • position: buffer中下一个要被读取或者写入的位置。每当读取或者写入一个数据之后,position的值会自动向后移一位
  • mark: 在buffer的某个位置设置的标记。

上述四个变量彼此之间必须遵守下面的大小关系:

mark <= position <= limit <= capacity

2.1.2 Buffer的基本使用方法
  • Buffer分配
ByteBuffer buf = ByteBuffer.allocate(64);       //创建一个可以容纳64个字节的缓冲区
CharBuffer buf = CharBuffer.allocate(64);       //创建一个可以容纳64个char类型的缓冲区
IntBuffer buf = IntBuffer.allocate(64);         //创建一个可以容纳64个Int类型的缓冲区
  • 从Buffer读取 / 写入数据

从Buffer中读取或者写入数据有两种方式:

  • 从Channel 读取 / 写入到Buffer
  • 通过Buffer的 put()方法写到Buffer里 / get()方法从Buffer中读取
int bytesRead = inChannel.read(buf);            //从Channel写入到Buffer
buf.put(127);                                   //put()方法写到Buffer中
int bytesWritten = inChannel.write(buf);        /
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值