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