nio、bio区别,应运场景
bio阻塞i/o
a.面向流的,InputStream(),OuputStream字节输入流,字节输出流,Reader,Writer字符输入流,字符输出流
b.阻塞的IO,比如Socket,它的底层用的BIO机制,accept()、connect()、write()调用时会产生阻塞。阻塞模型的局限性:不可能应对高并发、搞访问量的场景
总结:BIO方式适用于连接数目比较小并且一次发送大量数据的场景,这种方式对服务器资源要求比较高,并发局限于应用中
很简单转换成图型说明就是web浏览器发一个请求过来,web服务器就要new 一个线程来处理这个请求,这是传统的请求处理模型,这也就引来一个很大的问题,当请求越多,服务器端的启用线程也要越多,我们都知道linux(window)的文件句柄数有是限的,默认是1024,当然可以修改,上限好像是65536 ,(一个柄也相当于一个socket也相当于一个thread,linux查看文件句柄Unlimit -a) 其实在实际当中只要并发到1000上下响应请求就会很慢了,所以这种模型是有问题的,这种也就是同步阻塞IO编程(JAVA BIO)

以下是简单的bio例子:
Server端代码:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* @author
* @date 2019-02-27
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket socket = new ServerSocket();
socket.bind(new InetSocketAddress(9999));
while(true) {
Socket sc = socket.accept();
new Thread(new Accept(sc)).start();
}
}
}
class Accept implements Runnable{
private Socket sc = null;
public Accept(Socket sc) {
sc = this.sc;
}
@Override
public void run() {
System.out.println("提供服务的线程id是:"+Thread.currentThread().getId());
}
}
Clinet端代码
/**
*
* @author
* @date 2019-02-27
*/
public class Client {
public static void main(String[] args) throws IOException {
Socket sc = new Socket();
sc.connect(new InetSocketAddress( "127.0.0.1",9999),0);
while(true) {
}
}
}
启动server端,然后多次启动client端,打印结果如下

nio非阻塞i/o
a.面向缓冲区的(Buffer),NIO是通过缓冲区去操作数据的,可以用缓冲区灵活操作数据,此外,NIO是面向通道的(Channel),在通道上,即可以读数据,也可以写数据
b.NIO是非阻塞的IO,可以利用NIO处理高并发和高访问量的场景,NIO适合处理连接数目特别多,但是连接比较短(轻操作)的场景,Jetty,Mina,ZooKeeper等都是基于java的nio实现。服务器需要支持超大量的长时间连接。比如10000个连接以上,并且每个客户端并不会频繁地发送太多数据
首先,引入nio的3个相关概念:
1> Buffer 缓冲区
难用的buffer是一个抽象的对象,下面还有ByteBuffer,IntBuffer,LongBuffer等子类,相比老的IO将数据直接读/写到Stream对象,NIO是将所有数据都用到缓冲区处理,它本质上是一个数组,提供了位置,容量,上限等操作方法,还是直接看代码代码来得直接
2>Channel 通道
如自来水管一样,支持网络数据从Channel中读写,通道写流最大不同是通道是双向的,而流是一个方向上移动(InputStream/OutputStream),通道可用于读/写或读写同时进行,它还可以和下面要讲的selector结合起来,有多种状态位,方便selector去识别. 通道分两类,一:网络读写(selectableChannel),另一类是文件操作(FileChannel),我们常用的是上面例子中的网络读写!
3>Selector 多路复用选择器
它是神一样存在的东西,多路复用选择器提供选择已经就绪的任务的能力,也就是selector会不断轮询注册在其上的通道(Channel),如果某个通道发生了读写操作,这个通道处于就绪状态,会被selector轮询出来,然后通过selectionKey可以取得就绪的Channel集合,从而进行后续的IO操作.
一个多路复用器(Selector)可以负责成千上万个Channel,没有上限,这也是JDK使用epoll代替了传统的selector实现,获得连接句柄没有限制.这也意味着我们只要一个线程负责selector的轮询,就可以接入成千上万个客户端,这是JDK,NIO库的巨大进步.

以下是server端代码:
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class NioServer {
public static void main(String[] args) throws Exception {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
ssc.bind(new InetSocketAddress(6666));
Selector selector = Selector.open();
ssc.register(selector,SelectionKey.OP_ACCEPT);
while(true) {
selector.select();
Set<SelectionKey> set = selector.selectedKeys();
//获取事件结合的迭代器
Iterator<SelectionKey> iter = set.iterator();
while(iter.hasNext()) {
SelectionKey sk = iter.next();
if(sk.isAcceptable()) {
//证明有客户端请求建立回迁连接
ServerSocketChannel ss = (ServerSocketChannel)sk.channel();
//创建会话对象
SocketChannel sc = null;
while(sc==null) {
sc = ss.accept();
}
//设置为非阻塞模式
sc.configureBlocking(false);
//输出为客户端提供服务的线程ID
System.out.println("有客户端连入,负责提供服务的"
+ "线程id:"+Thread.currentThread().getId());
//为sc注册read事件和write事件
sc.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
}
if(sk.isReadable()) {
//获取SocketChannel对象
SocketChannel sc = (SocketChannel)sk.channel();
ByteBuffer buf = ByteBuffer.allocate(10);
sc.read(buf);
System.out.println("服务器端独到的内容:"
+new String(buf.array()));
System.out.println("负责处理读请求的线程ID:"
+Thread.currentThread().getId());
sc.register(selector,sk.interestOps()&~SelectionKey.OP_READ);
}
if(sk.isWritable()) {
//获取SocketChannel对象
SocketChannel sc = (SocketChannel)sk.channel();
ByteBuffer buf = ByteBuffer.wrap("over".getBytes());
sc.write(buf);
System.out.println("负责处理写请求的线程ID:"
+Thread.currentThread().getId());
sc.register(selector,sk.interestOps()&~SelectionKey.OP_WRITE);
}
//删除该事件,目的:为了防止同一个事件被处理多次
iter.remove();
}
}
}
}
以下是client端代码
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class NIOClient {
public static void main(String[] args) throws Exception {
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
sc.connect(new InetSocketAddress("127.0.0.1", 6666));
while(!sc.isConnected()) {
sc.finishConnect();
}
ByteBuffer buf = ByteBuffer.wrap("helloworld".getBytes());
sc.write(buf);
ByteBuffer readBuf = ByteBuffer.allocate(9);
Thread.sleep(1000);
sc.read(readBuf);
System.out.println("客户端读取到服务器发送过来的内容:"
+new String(readBuf.array()));
while(true) {
}
}
}
这里补充一点aio,这个比NIO先进的技术,最终实现了
netty
这是神一样存在的java nio框架, 这个偏底层的东西,可能你接触较少却又无处不在,比如:

在业界有一篇无法超越的netty入门文章,我也没这个能力超越,只能双手奉上,你们好好研读,必然学有所成!
http://ifeve.com/netty5-user-guide/
本文部分参考于:
https://www.cnblogs.com/barrywxx/p/8430790.html
nio、bio区别,应运场景的更多相关文章
- 三分钟秒懂BIO/NIO/AIO区别?
首先来举个例子说明吧,假设你想吃一份盖饭: 同步阻塞:你到饭馆点餐,然后在那等着,还要一边喊:好了没啊! 同步非阻塞:在饭馆点完餐,就去遛狗了.不过溜一会儿,就回饭馆喊一声:好了没啊! 异步阻塞:遛狗 ...
- NIO/BIO
NIO/BIO BIO网络通信 概述 网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地 ...
- Java NIO:IO与NIO的区别 -阿里面试题
一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...
- BIO,NIO的区别,使用场景。
一.什么是io? i就是input,输入,o就是output,输出,合起来就是以流为基本的输入输出. 二.传统的io 传统的服务器端同步阻塞I/O处理(也就是BIO,Blocking I/O): 当客 ...
- java 中AIO,BIO,NIO的区别(茅塞顿开)
看到知乎上一篇回答,解决了疑惑:https://www.zhihu.com/question/56673416 第三位作者的回答...原谅我没有登录知乎,不然一定给他留赞. 也可以参考:https:/ ...
- io与Nio的区别及实用场景
https://blog.csdn.net/wodeyuer125/article/details/39475207
- Java之NIO,BIO,AIO
Hollis知识星球的一些学习笔记,有兴趣的朋友可以微信搜一下 什么是NIO 什么是IO? 它是指计算机与外部世界或者一个程序与计算机的其余部分的之间的接口.它对于任何计算机系统都非常关键,因而所有 ...
- 关于同步,异步,阻塞,非阻塞,IOCP/epoll,select/poll,AIO ,NIO ,BIO的总结
相关资料 IO基本概念 Linux环境 同步异步阻塞非阻塞 同步与异步 阻塞与非阻塞 IO模型Reference Link 阻塞IO模型 非阻塞IO模型 IO复用模型 信号驱动异步IO模型 异步IO模 ...
- 【转载】Java NIO学习 & NIO BIO AIO 比较
可以参考这个页面: http://www.iteye.com/magazines/132-Java-NIO (下面这个页面也有) http://ifeve.com/overview/ 另,在这篇文章里 ...
随机推荐
- C# Winform 仪表盘
winform 仪表盘相关下载链接://download.csdn.net/download/floweroflvoe/10432601?utm_source=bbsseo 控件首次拖拽上来是这样的: ...
- mysql权限参考
mysql日常管理和应用工作中,大家经常会涉及到授权问题,下面,我们就列举下权限相关的参考. 1.管理权限(Administrative Privileges) Privilege Name ...
- linux下sort命令详解
1 sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出. [rocrocket@rocrocket progr ...
- Code Reading: ORB-SLAM回环检测源码阅读+注释
之前研究过一些回环检测的内容,首先要看的自然是用词袋回环的鼻祖和正当继承人(没有冒犯VINS和LDSO的意思)ORB-SLAM.下面是我的代码注释.因为代码都是自己手打的,不是在源码上注释的,所以一些 ...
- MFC界面分割以及挂载
MFC中文档与视图(二) Last Edit 2013/11/19 这篇主要是介绍一下怎么去分割视图. 视图的分割分为:动态分割,静态分割.所谓的静态分割是指软件一启动视图就分割完成,而动态分割是在 ...
- 版本管理工具小乌龟TortoiseGit的安装和使用(2)
内容中包含 base64string 图片造成字符过多,拒绝显示
- [Codeforces375E]Red and Black Tree
Problem 给定一棵有边权的树.树上每个点是黑或白的.黑白点能两两交换. 求符合任意一个白点到最近黑点的距离小于等于x时,黑白点交换次数最少为多少. Solution 明显是一题树形DP.我们先跑 ...
- min_25筛题目总结
看了网上众多博客后,我才发现,实现min_25只有脑子,没有代码. 当然可能是我太ruo了. min_25是一种想法,不是算法. 不要尝试套模板,因为很多题目并没有什么用. 最重要的一点,g不要看成是 ...
- api接口开发跨域注意事项和设置
因为跨域请求会先发送一个OPTIONS请求,所以需要判断下OPTIONS请求的就直接返回 if(strtoupper($_SERVER['REQUEST_METHOD'])== 'OPTIONS'){ ...
- python常见问题汇总
1.python使用selenium中的时间等待 a.强制等待 time.sleep() b.隐式等待: 如果某些元素不是立即可用的,隐式等待是告诉WebDriver去等待一定的时间后去查找元素. 默 ...