JAVA NIO 之NIO简介

复习NIO知识,权当做笔记~~

在NIO之前先复习一下

1、I/O类简图

 2、通常我们把网络通信也归到IO行为中,例如网络编程中的scoket通信。

不管是磁盘I/O,还是网络I/O,数据在写入OutputStream和从InputStream中读取数据都可能发生阻塞即BIO,一旦阻塞,线程就失去CPU的使用权,影响性能。所以我们就需要另一种IO---NIO

比如我们用ServerScoket写一个接受tcp消息的服务器,思路是绑定端口,调用accept()阻塞等待客服端链接。请看下面代码实现:

/**
 * @author monkjavaer
 * @date 2018/09/28 23:39
 */
public class oioTest {


    public static void main(String[] args) {


        try {
            //创建socket服务,监听5196端口
            ServerSocket server=new ServerSocket(5196);
            System.out.println("TCP server start!");
            while(true){
                //获取一个套接字
                //accept阻塞
                Socket socket = server.accept();
                System.out.println("接收到了。。。。。。。");
                System.out.println(socket.getInetAddress() + ":" +socket.getPort());
                byte[] bytes = new byte[1024];
                InputStream inputStream = socket.getInputStream();
                while(true){
                    //读取数据(阻塞)
                    int read = inputStream.read(bytes);
                    if(read != -1){
                        System.out.print(new String(bytes, 0, read));
                    }else{
                        break;
                    }
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

  

windows系统中开启telnet服务,输入以下命令测试:telnet 127.0.0.1 5196

上面的程序是一个scoket对应一个thread,但是如果有10个客服端怎么办呢?

这里在收到消息后可以通过线程池来处理。借用一张流行的图表示:

但如果有成千上万的客服端,这种方法就不行了。因为线程上下文切换在高并发时非常困难,这也是同步阻塞的低扩展劣势。但NIO的多路复用可以解决此问题,多路复用后面再写,先来看看下面的基础介绍:

NIO主要组成部分

缓冲区(Buffer)一个Buffer对象是固定数量的数据的容器。其作用是一个存储器,或者分段运输区,在这里数据可被存储并在之后用于检索。ByteBuffer、IntBuffer、CharBuffer、LongBuffer、DoubleBuffer、FloatBuffer、ShortBuffer都是其实现类。

通道(Channel)Channel 用于在字节缓冲区和位于通道另一侧的实体(通常是一个文件或套接字)之间有效地传输数据。

选择器(Selector):是 NIO 实现多路复用的基础,它提供了一种高效的机制,可以检测到注册在 Selector 上的多个 Channel 中,是否有 Channel 处于就绪状态,进而实现了单线程对多Channel 的高效管理。

总之NIO就是提升 Java 用程序的 I/O 效率 

下篇文章将详细记录NIO之Buffer

原文地址:https://www.cnblogs.com/monkjavaer/p/9775500.html