BIO
在IO时是阻塞状态,优点是代码简单、直观,缺点是IO的效率和可扩展性瓶颈。
NIO
发送请求后不阻塞
NIO的核心
NIO-Channels
NIO-Buffers
NIO-Selector
允许单线程处理多个Channel,如果一个线程有多个连接,每个连接流量很低,此时用Selector就很方便,例如聊天服务器。
Selector有一个public abstract SelectorProvider provider();
方法,方法的实现是这样的
public static SelectorProvider provider() {
synchronized (lock) {
if (provider != null)
return provider;
return AccessController.doPrivileged(
new PrivilegedAction<SelectorProvider>() {
public SelectorProvider run() {
if (loadProviderFromProperty())
return provider;
if (loadProviderAsService())
return provider;
provider = sun.nio.ch.DefaultSelectorProvider.create();
return provider;
}
});
}
}
加载provider,如果两个if都不能加载,那就回通过sun.nio.ch.DefaultSelectorProvider.create();
创建一个,源码如下,查看的是solaris 版本的JDK:
/**
* Returns the default SelectorProvider.
*/
public static SelectorProvider create() {
String osname = AccessController
.doPrivileged(new GetPropertyAction("os.name"));
if (osname.equals("SunOS"))
return createProvider("sun.nio.ch.DevPollSelectorProvider");
if (osname.equals("Linux"))
return createProvider("sun.nio.ch.EPollSelectorProvider");
return new sun.nio.ch.PollSelectorProvider();
}
源码链接http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/d8bd882cfd2a/src/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java
从源码可以看到IO多路复用,在于单线程可以同时处理多个IO,调用系统级别的select\poll\epoll,由系统监控IO状态
select、poll、epoll的区别
AIO
用户操作直接返回,不会阻塞。AIO属于异步处理模型,用户线程可以同时处理别的线程