码迷,mamicode.com
首页 > 其他好文 > 详细

关于BIO,NIO,AIO的理解

时间:2019-07-29 11:33:12      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:main   com   私有   nts   转化   art   ddr   let   通道数   

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 }
View Code
技术图片
 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 }
View Code

 

关于BIO,NIO,AIO的理解

标签:main   com   私有   nts   转化   art   ddr   let   通道数   

原文地址:https://www.cnblogs.com/fan123yh/p/11262855.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!