网络i/o编程3 NIO

一 NIO

1.1 介绍

1.NIO:为同步非阻塞。位于java的 java.nio.*包下,NIO三大核心部分:

  1. Channel 通道
  2. Buffer 缓冲区:底层使用Unsafe类直接操作内存,Buffer中写入的所有数据jvm都不进行管理,不能被gc回收。
  3. Selector 选择器

2.NIO是面向缓冲区的。当数据读取到一个它稍后处理的缓冲区,需要时可在缓存区中前后移动,这就增加了处理过程中的灵活性,使用它可以提供非阻塞式的高伸缩性网络。

3.通俗讲NIO的同步非阻塞:NIO是可以做到用一个线程来处理多个操作的,假设有10000个请求过来,根据实际情况,可以分配50个或者100个线程来处理,不像之前的阻塞IO那样,非得1000个。

其中http2.0采用多路复用技术,做到同一个连接并发处理多个请求,而且并发请求的数量比http1.1大了好多个数量级。

1.2 Buffer的简单操作案例

package com.ljf.netty.nio;

import java.nio.IntBuffer;

/**
 * @ClassName: BufferDemo
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/05/12 22:37:50
 * @Version: V1.0
 **/
public class BufferDemo {
    public static void main(String[] args) {
        IntBuffer  intBuffer=IntBuffer.allocate(5);
        for(int k=0;k<intBuffer.capacity();k++){
            intBuffer.put(k*30);
        }
        //读取数据,将写切换成读模式
        intBuffer.flip();
        while(intBuffer.hasRemaining()){
            System.out.println("读取:"+intBuffer.get());
        }
    }
}

结果:

1.3 flip()方法的作用

1.4 BIO和NIO的区别

BIO是阻塞的,NIO则是非阻塞的。

BIO是以流的方式处理数据,而NIO是以缓存区(缓存块)的方式处理数据,缓存块的I/O效率比流的I/O效率高很多。
BIO基于字节流和字符流进行操作,而NIO基于channel(通道)和Buffer(缓存区)进行操作,数据总是从通道读取到缓存区中,或者从缓冲区写入到通道中。
selector(选择器)用于监听多个通道的事件(比如:连接请求、数据到达等),因此使用单个线程就可以监听多个客户端通道。

1.5 NIO的3大组件核心关系

1. 1个selector对应一个线程,一个线程对应多个channel。1:n关系。

2.每个channel都会对应一个Buffer。1:1关系

3.selecotr会根据不同的事件,在各个通道上进行切换

4.Buffer就是一个内存块,底层是一个数组,数据的读取写入都是通过Buffer。其中BIO中要么是输入流,要么是输出流,不能双向。但是NIO的Buffer是可以读也可以写的。需要flip方法切换。

5.channel是双向的,可以返回底层操作系统的情况,比如linux,底层的操作系统。

二 NIO的buffer

2.1 buffer

缓存区(Buffer):缓存区本质上是一个可以读写数据的内存块,可以理解成是一个容器对象(含数组),该对象提供了一组方法,可以更轻松地使用内存块,缓存区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化请,channel提供从文件、网络读取数据的渠道。但是读取或写入的数据都必须经由buffer,如图

2.2  常见缓存区类型

1.在NIO中,buffer是一个顶层父类,它是一个抽象类。常用的子类
ByteBufer: 存储字节数据到缓存区
ShortBuffer:存储字符串数据到缓存区
CharBuffer:存储字符数据到缓存区
IntBuffer:存储整数数据到缓存区
LongBuffer:存储长整型数据到缓冲区
DoubleBuffer:存储小数到缓冲区
FloatBuffer:存储小数到缓存区。
注意可以看出:java中的基本数据类型(boolean)除外,都有一个Buffer类型与之对应。

2.3 缓存区重要方法属性

2.4 常见方法属性

数学关系:-1<= mark <= positon <= limit <= capacity
mark: 标记着当前position可读或可写的索引值
position:指向下一次可读或者可写的索引值
limit:可读可写的索引一定是小于它的,不能等于它
capacity:数组容量,一旦初始化好了,便永远无法修改

 

mark方法:标记将开始可操作位置索引标记一下,

reset方法:将之前标记的位置索引,重新赋值给可操作位置索引。

 三  NIO的通道

3.1 NIO的通道与普通数据流的区别

1.Nio的通道类似流,但是可以同时进行读写,而流只能读或者只能写,例如BIO的stream是单向的,FileInputStream对象只能进行读取数据操作。
2.通道可以实现异步读写数据,可以从缓存读数据,也可以写数据到缓存中。
3.channel是NIO的一个接口,常见的有filechannel,Datagramchannel,serversocketchannel等
4.FileChannel用于文件的数据读写,DatagramChanel用户udp的数据读写,
serversocketChannel和socketchannel用于Tcp的数据读写。

3.2 常见方法的作用

public int read(ByteBuffer dst): 从通道读取数据并放到缓存区中。
public int write(ByteBuffer src):把缓存区的数据写到通道中。

public long transferFrom(ReadableByteChannel src,long position,long cout):从源通道中复制数据到当前通道。
public long transferTo(long position,long cout,ReadableByteChannel dst):从当前通道复制数据到目标通道
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值