关于BIO,NIO,AIO的理解
Posted fan123yh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于BIO,NIO,AIO的理解相关的知识,希望对你有一定的参考价值。
BIO:同步阻塞式IO
NIO:同步非阻塞式IO
AIO(NIO2.0):异步非阻塞式IO
同步:指虚拟机来完成IO读写,如果读写没有完成程序一直等待。
异步:指将读写交给操作系统来做,java代码要干的事就是将想读的写的东西给操作系统然后返回状态值,最后让操作系统通知程序是否完成。
阻塞:指对网络通信,一个客户端对应一个服务器线程,当链接数量多的时候,就会发生阻塞,其余的客户端连不上服务器。
非阻塞:将所谓的一个链接对应一个线程转化为一个请求对应一个线程,这里引入了通道和多路复用技术,由多路复用器来轮询通道是否请求读写,然后创建一个线程来处理他。
异步一般与操作系统关系比较密切,不同的操作系统异步的效率也是不一样的。
阻塞是可以用代码方式体现的:
1.创建服务器类,创建私有多路复用器,和buffer缓冲区对象。
2.创建服务器类的构造方法,通道绑定地址并且绑定通道设置监听。
3.创建客户端类,绑定通道,并用buffer输入通道。
1 package com.fan; 2 3 import java.io.IOException; 4 import java.net.InetSocketAddress; 5 import java.nio.ByteBuffer; 6 import java.nio.channels.SelectionKey; 7 import java.nio.channels.Selector; 8 import java.nio.channels.ServerSocketChannel; 9 import java.nio.channels.SocketChannel; 10 import java.util.Iterator; 11 12 public class Server implements Runnable 13 14 private Selector selector;//创建多路复用器。 15 16 private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);//创建ByteBuffer,并分配长度。 17 18 public Server(int port) //创建构造函数。 19 try 20 21 this.selector = Selector.open();//打开多路复用器。 22 23 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();//打开服务器通道channel。 24 25 serverSocketChannel.configureBlocking(false);//设置该多通道为非阻塞的。 26 27 serverSocketChannel.bind(new InetSocketAddress(port));//给通道绑定服务器地址。 28 29 serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);//通道注册到多路复用器中,并设置监听事件。 30 31 System.out.println("Server start, port :" + port); 32 33 catch (Exception e) 34 35 36 37 38 @Override 39 public void run() 40 while (true) 41 try 42 this.selector.select();//让多路复用器进行监听。 43 44 Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator();//返回多路选择器已经选择的集。 45 46 while (iterator.hasNext()) //进行遍历。 47 48 SelectionKey selectionKey = iterator.next();//获取一个选择的元素。 49 50 iterator.remove();//将容器移除。 51 52 if (selectionKey.isValid()) 53 if (selectionKey.isAcceptable()) 54 this.accept(selectionKey); 55 56 if (selectionKey.isReadable()) 57 this.read(selectionKey); 58 59 if (selectionKey.isWritable()) 60 //this.write(selectionKey); //ssc 61 62 63 64 65 catch (Exception e) 66 67 68 69 70 71 private void write(SelectionKey key) 72 //ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); 73 //ssc.register(this.seletor, SelectionKey.OP_WRITE); 74 75 76 private void read(SelectionKey key) 77 try 78 this.byteBuffer.clear();//清空缓冲区旧的数据 79 80 SocketChannel socketChannel = (SocketChannel) key.channel();//获取之前注册的socket通道对象 81 82 int read = socketChannel.read(this.byteBuffer);//将通道数据读到buffer中 83 84 if(read==-1)//如果没数据就返回 85 key.channel().close(); 86 key.cancel(); 87 return; 88 89 90 this.byteBuffer.flip();//有数据则进行读取 读取之前需要进行复位方法(把position 和limit进行复位) 91 92 byte[] bytes = new byte[this.byteBuffer.remaining()];//根据缓冲区的数据长度创建相应大小的byte数组,接收缓冲区的数据 93 94 this.byteBuffer.get(bytes);// 接收缓冲区数据 95 96 String body = new String(bytes).trim(); 97 98 System.out.println("Server : " + body); 99 100 catch (Exception e) 101 102 103 104 private void accept(SelectionKey key) 105 106 try 107 ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel(); 108 SocketChannel accept = serverSocketChannel.accept(); 109 accept.configureBlocking(false); 110 accept.register(this.selector, SelectionKey.OP_READ); 111 catch (Exception e) 112 113 114 115 116 public static void main(String[] args) 117 118 new Thread(new Server(8765)).start(); 119 120 121 122
1 package com.fan; 2 3 import java.io.IOException; 4 import java.net.InetSocketAddress; 5 import java.nio.ByteBuffer; 6 import java.nio.channels.SocketChannel; 7 8 public class Client 9 10 11 public static void main(String[] args) 12 InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8765); 13 14 SocketChannel sc = null; 15 16 ByteBuffer buf = ByteBuffer.allocate(1024); 17 18 try 19 20 sc = SocketChannel.open(); 21 22 sc.connect(address); 23 24 while (true) 25 26 byte[] bytes = new byte[1024]; 27 28 System.in.read(bytes); 29 30 buf.put(bytes); 31 32 buf.flip(); 33 34 sc.write(buf); 35 36 buf.clear(); 37 38 39 40 catch (IOException e) 41 42 e.printStackTrace(); 43 44 finally 45 46 if (sc != null) 47 48 try 49 50 sc.close(); 51 52 catch (IOException e) 53 54 e.printStackTrace(); 55 56 57 58 59 60 61 62 63 64
以上是关于关于BIO,NIO,AIO的理解的主要内容,如果未能解决你的问题,请参考以下文章