- BIO服务器端的实现模式是一个连接一个线程,即客户端有连接请求时需要启动一个线程进行处理,可以通过线程池进行管理,但创建开销比较大并且创建线程数量有限。
- NIO是同步非阻塞的,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器(Selector)上,多路复用轮询到连接有I/O请求时才启动一个线程进行处理。
BIO与NIO一个比较重要的不同,是我们使用BIO的时候往往会引入多线程,每个连接一个单独的线程,而NIO则是使用单线程或者使用少量的多线程,每个连接公用一个线程。- AIO异步非阻塞,服务器实现模式是一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
以上是网络IO,下面是磁盘IO:
BIO是同步阻塞试的,都是通过字节的移动来处理的,也就是说面向流的输入/输出系统一次只能处理一个字节,因此面向流的IO系统通常效率不高。
NIO是面向块的处理,采用内存映射文件的方式来处理输入/输出,NIO将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样来访问文件了。NIO包含两个核心对象Channel(通道)和Buffer(缓冲)。
看下源码:
package java.nio.channels;
import java.io.IOException;
import java.io.Closeable;
public interface Channel extends Closeable {
public boolean isOpen();
public void close() throws IOException;
}
Buffer可以被理解为一个容器,本质是一个数组,发送到Channel的所有对象都必须先放到Buffer中,从Channel中读取的数据也必须先读到Buffer中。
mark <= position <= limit <= capacity
package java.nio;
import java.util.Spliterator;
public abstract class Buffer {
static final int SPLITERATOR_CHARACTERISTICS =
Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
// Invariants: mark <= position <= limit <= capacity
private int mark = -1;
private int position = 0;
private int limit;
private int capacity;
long address;
Buffer(int mark, int pos, int lim, int cap) { // package-private
if (cap < 0)
throw new IllegalArgumentException("Negative capacity: " + cap);
this.capacity = cap;
limit(lim);
position(pos);
if (mark >= 0) {
if (mark > pos)
throw new IllegalArgumentException("mark > position: ("
+ mark + " > " + pos + ")");
this.mark = mark;
}
}
//后面的方法省略。。。。。
}