一、BIO

Blocking IO(即阻塞IO);

1.      特点:

a)   Socket服务端在监听过程中每次accept到一个客户端的Socket连接,就要处理这个请求,而此时其他连接过来的客户端只能阻塞等待;

b)   多线程处理多个连接,每个线程拥有自己的栈空间并且占用一些 CPU 时间。每个线程遇到外部未准备好的时候,都会阻塞掉。阻塞的结果就是会带来大量的线程上下文切换。且大部分线程上下文切换可能是无意义的。比如假设一个线程监听一个端口,一天只会有几次请求进来,但是该 cpu 不得不为该线程不断做上下文切换尝试,大部分的切换以阻塞告终。

2.      流程:

二、 NIO

Java New IO(即非阻塞IO )

1.      特点:

a)   由一个专门的线程来处理所有的 IO 事件,并负责分发。

b)   事件驱动机制:事件到的时候触发,而不是同步的去监视事件。

c)   线程通讯:线程之间通过 wait,notify 等方式通讯。保证每次上下文切换都是有意义的。减少无谓的进程切换。

2.      示例:

服务器端:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.socket().bind(new InetSocketAddress(9999));

while(true){

SocketChannel socketChannel = serverSocketChannel.accept();

//do something with socketChannel...

}

客户端:

SocketChannel socketChannel = SocketChannel.open();

socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));

ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = socketChannel.read(buf);

String newData = "New String to write to file";

ByteBuffer buf = ByteBuffer.allocate(48);

buf.clear();

buf.put(newData.getBytes());

buf.flip();

while(buf.hasRemaining()) {

channel.write(buf);

}

3.      Channels(通道):

重要实现类:

1)   FileChannel:从文件中读写数据。

2)   DatagramChannel:能通过UDP读写网络中的数据。

3)   SocketChannel:能通过TCP读写网络中的数据。

4)   ServerSocketChannel:可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。

重要方法:

Read(buf):从通道中读出数据到buf中;

Write(buf):将buf中的数据写入到通道中;

其中FileChanel提供了Map方法,返回一个MappedByteBuffer对象,代表内存映射文件IO,它可以比常规的基于流或者基于通道的I/O快的多。内存映射文件I/O是通过使文件中的数据出现为 内存数组的内容来完成的。

4.      Buffers(缓冲区):

本质上是一块可以写入数据,然后可以从中读取数据的内存。用于和NIO通道进行交互(数据是从通道读入缓冲区,从缓冲区写入到通道中的);

继承关系:

重要属性:

序号

名称

属性功能

说明

1

capacity

缓冲区大小

缓冲内存区域总的字节大小;

2

limit

实际数据大小

读模式时, limit表示你最多能读到多少数据;写模式下,表示你最多能往Buffer里写多少数据;写模式下,limit等于Buffer的capacity。

3

position

当前位置

表示当前的位置。初始的position值为0,position最大可为capacity–1;

重要方法:

序号

方法名

方法功能

说明

1

Flip

切换到读模式

用于从写模式切换到读模式时调用的一个方法,表示最多能读取到多少内容;

具体实现为: 将position设回0,并将limit设置成之前position的值;

2

rewind

重读Buffer中的所有数据;

将position设回0,limit保持不变,仍然表示能从Buffer中读取多少数据;

3

Clear

compact

清空缓冲区

limit用于将整个缓冲区全部清空,而compact用于在缓冲区还有部分未读完的数据时,将未读完的数据拷贝到缓冲区最前面,将其余部分全部清空;

limit和compact在清除缓冲区时都是修改的指针,使得往缓冲区里面写入数据时能覆盖,并不会真正清空缓冲区里面的内容;

4

Mark

reset

标记

恢复标记

mark()方法标记Buffer中的一个特定position。通过调用reset()方法恢复这个position;

5

Equals

compareTo

判断是否相等

比较大小

equals相等的条件:

1.有相同的类型(byte、char、int等)。

2.Buffer中剩余的byte、char等的个数相等。

3.Buffer中所有剩余的byte、char等都相同。

compareTo:判断Buffer A小于Buffer B的条件:

1.第一个不相等的元素小于另一个Buffer中对应的元素 。

2.所有元素都相等,但第一个Buffer比另一个先耗尽(第一个Buffer的元素个数比另一个少)。

备注:剩余元素是从 positionlimit之间的元素

6

slice

缓冲区分片

根据现有的缓冲区对象来创建一个子缓冲区,即在现有缓冲区上切出一片来作为一个新的缓冲区,但现有的缓冲区与创建的子缓冲区在底层数组层面上是数据共享的,也就是说,子缓冲区相当于是现有缓冲区的一个视图窗口

7

asReadOnlyBuffer

创建只读缓冲区

这个方法返回一个与原缓冲区完全相同的缓冲区,并与原缓冲区共享数据,只不过它是只读的。如果原缓冲区的内容发生了变化,只读缓冲区的内容也随之发生变化;

8

allocateDirect

直接缓冲区

给定一个直接字节缓冲区,Java虚拟机将尽最大努 力直接对它执行本机I/O操作。也就是说,它会在每一次调用底层操作系统的本机I/O操作之前(或之后),尝试避免将缓冲区的内容拷贝到一个中间缓冲区中 或者从一个中间缓冲区中拷贝数据。

5.      Selectors(选择器):

选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。

要使用Selector,得向Selector注册Channel,然后调用它的select()方法,接下来就等待事件就绪并处理事件;

使用事项:

1)   与Selector一起使用时,Channel必须处于非阻塞模式下。这意味着不能将FileChannel与Selector一起使用,因为FileChannel不能切换到非阻塞模式。而套接字通道都可以。

2)   选择器监听的事件集合有:SelectionKey.OP_CONNECT, SelectionKey.OP_ACCEPT, SelectionKey.OP_READ, SelectionKey.OP_WRITE;

3)   从SelectionKey中分离出事件的方法:

int interestSet = selectionKey.interestOps();

boolean isInterestedInAccept=(interestSet & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT;

boolean isInterestedInConnect = (interestSet & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT;

boolean isInterestedInRead = (interestSet & SelectionKey.OP_READ) == SelectionKey.OP_READ;

boolean isInterestedInWrite = (interestSet & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE;

同样SelectionKey中也封装了上面的方法:

selectionKey.isAcceptable();

selectionKey.isConnectable();

selectionKey.isReadable();

selectionKey.isWritable();

使用流程:

java BIO/NIO的更多相关文章

  1. Java BIO NIO 与 AIO

    回顾 上一章我们介绍了操作系统层面的 IO 模型. 阻塞 IO 模型. 非阻塞 IO 模型. IO 复用模型. 信号驱动 IO 模型(用的不多,知道个概念就行). 异步 IO 模型. 并且介绍了 IO ...

  2. JAVA bio nio aio

    [转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? ...

  3. java BIO/NIO/AIO 学习

    一.了解Unix网络编程5种I/O模型 1.1.阻塞式I/O模型 阻塞I/O(blocking I/O)模型,进程调用recvfrom,其系统调用直到数据报到达且被拷贝到应用进程的缓冲区中或者发生错误 ...

  4. 3. 彤哥说netty系列之Java BIO NIO AIO进化史

    你好,我是彤哥,本篇是netty系列的第三篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们介绍了IO的五种模型,实际上Java只支持其中的三种,即BIO/NIO/ ...

  5. JAVA BIO,NIO,Reactor模式总结

    传统同步阻塞I/O(BIO) 在NIO之前编写服务器使用的是同步阻塞I/O(Blocking I/O).下面是一个典型的线程池客服端服务器示例代码,这段代码在连接数急剧上升的情况下,这个服务器代码就会 ...

  6. java BIO NIO IO

    参考 https://www.cnblogs.com/zedosu/p/6666984.html 摘要: 关于BIO和NIO的理解 最近大概看了ZooKeeper和Mina的源码发现都是用Java N ...

  7. I/O模型系列之三:IO通信模型BIO NIO AIO

    一.传统的BIO 网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请 ...

  8. (转)也谈BIO | NIO | AIO (Java版)

    原文地址: https://my.oschina.net/bluesky0leon/blog/132361 关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一 ...

  9. Java BIO、NIO、AIO 学习(转)

    转自 http://stevex.blog.51cto.com/4300375/1284437 先来个例子理解一下概念,以银行取款为例: 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Ja ...

随机推荐

  1. CPU的硬件结构和汇编语言

    (已更正) 这个问题包括CPU的硬件结构和汇编语言的范畴. 这里梳理一下. 首先, 题主"李建国"自问自答的部分说的是正确的, CPU的指令集是软件与CPU这两个层级之间的接口, ...

  2. pragma comment的使用 pragma预处理指令详解

    pragma comment的使用 pragma预处理指令详解   #pragma comment( comment-type [,"commentstring"] ) 该宏放置一 ...

  3. WebView加载页面

    //使用内置浏览器webView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoa ...

  4. format格式

    The format part is where you can specify more precisely the format of the data that you expect. For ...

  5. 使用ext httpProxy代理获取列表但列表展示不全的问题解决

    今天项目中遇到一个奇葩的事情,使用ext的jsonstore通过httpproxy代理想要获取一个列表,页面显示是有五条数据的但是却只展示了2条,于是各种排查,后台确定无误后开始检查前台,发现浏览器中 ...

  6. shell脚本-实战防dos攻击

    根据web日志或者或者网络连接数,监控当某个IP并发连接数或者短时内PV达到100,即调用防火墙命令封掉对应的IP,监控频率每隔3分钟.防火墙命令为:iptables -I INPUT -s 10.0 ...

  7. Pycharm连接Git及使用

    环境: Git-2.7.2-32-bit_setup.1457942412.exe TortoiseGit-2.4.0.2-64bit.msi 安装配置Git后,打开Pycharm.file--> ...

  8. 构造方法调用另一个构造方法,用this

    using System; class Person { public int age; public string name; public Person(int age, string name) ...

  9. 1--Python 入门--Python基础数据类型

    一.Python基础语法 初次使用Python,首先要明确三点: Python的标识符(例如变量名.函数名等),可用字母.数字和下划线构成,不能以数字开头,且区分大小写. Python对于缩进敏感.在 ...

  10. HDU 6038 17多校1 Function(找循环节/环)

    Problem Description You are given a permutation a from 0 to n−1 and a permutation b from 0 to m−1. D ...