一.channel.spi底层实现我们首先看看SelectorProvider:
SelectorProvider提供了通过底层输出各种NIO实现的接口:
- public abstract DatagramChannel openDatagramChannel():创建并打开一个DatagramChannel...DatagramChannel.open()方法调用.
- public abstract SocketChannel openSocketChannel():创建并打开一个SocketChannel,SocketChannel.open()方法调用
- public abstract ServerSocketChannel openServerSocketChannel():由ServerSocketChannel.open()方法调用
- public abstract SocketChannel openSocketChannel():由SocketChannel.open()方法调用.
- public abstract Pipe openPipe():由Pile.open()调用
- public abstract AbstractSelector openSelector():此方法由Selector.open()调用
- public static SelectorProvider provider():获得当前应用所使用的provider;不同的OS,对IO Selector模型各不相同,JAVA API中也提供了与其适配的provider,那么对provider的选择是怎么做的呢?在静态方法provider中执行如下:
- 如果系统定义了"java.nio.channels.spi.SelectorProvider"参数,例如-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider,那么系统将会加载并使用此provider.(loadProviderFromProperty()).
- 如果对系统类加载器可见的jar文件中安装了provider,并且jar文件包含资源目录META-INF/services中名为java.nio.channels.spi.SelectorProvider的提供者配置文件,则遍历provider列表,并加载和初始化第一个类名称.
- 如果上述,都不能获得provider,将会通过DefaultSelectorProvider.create()获得结果.前两步均可以被应用开发者所操作.对于3)返回的结果可能在不同的JDK版本下有所不同.
/////代码样例(来自openJDK) public static SelectorProvider create() { PrivilegedAction pa = new GetPropertyAction("os.name"); String osname = (String) AccessController.doPrivileged(pa); if ("SunOS".equals(osname)) {//1、如果SunOS return new sun.nio.ch.DevPollSelectorProvider(); } //2、Linux 内核>=2.6 // use EPollSelectorProvider for Linux kernels >= 2.6 if ("Linux".equals(osname)) { pa = new GetPropertyAction("os.version"); String osversion = (String) AccessController.doPrivileged(pa); String[] vers = osversion.split("\\.", 0); if (vers.length >= 2) { try { int major = Integer.parseInt(vers[0]); int minor = Integer.parseInt(vers[1]); if (major > 2 || (major == 2 && minor >= 6)) { return new sun.nio.ch.EPollSelectorProvider(); } } catch (NumberFormatException x) { // format not recognized } } } return new sun.nio.ch.PollSelectorProvider(); }
可以简单归纳如下:在Solaris系统下将会使用DevPollSelectorProdiver;在Linux系统下(2.6+版本),将会使用EPollSelectorProvider;否则将会使用PollSelectorProvider.对于SunJDK,DefaultSelectorProvider将直接返回WindowsSelectorProvider.这是一种基于Poll机制.
二.多路IO复用模型:
目前广泛支持的多路IO复用模型:epoll,poll,devpoll,select.
- select:同步IO,目前已经不能再被推荐使用.缺点:单个进程能够监视(打开)的FD(文件描述符)的个数是有最大限制的(2048);select需要复制大量的句柄数据结构,产生巨大的开销;应用程序需要遍历句柄列表才能知道哪个句柄(socket)发生了事件.
- epoll:一种被认为性能最好的IO多路复用模型.这是一种异步IO,它能在大量并发连接环境中,显著提高性能.因为它互惠复用文件描述符集合来传递结果而迫使开发者每次都必须重新准备要被侦听的文件描述符集合,另一点原因是,获取事件时无需遍历整个被侦听的描述符集,而只需要遍历那些被内核IO事件异步唤醒加入Ready队列的描述符集合就行了.(事件可以被水平触发/边缘触发)
- 因为IO模型存在历史原因,它所涉及到的内容相当复杂,我们到此为止吧.
相关推荐
5. `java.nio.channels.spi`:类似的,这个包提供了Channel和Selector的SPI,用于扩展NIO API。 ByteBuffer是NIO中的关键类,它与其他类型的Buffer(如CharBuffer、IntBuffer等)一样,具有capacity、limit和...
- **`java.nio.channels.spi`**:定义了可用来实现 channel 和 selector API 的抽象类。 - **`java.nio.charset`**:定义了处理字符编码和解码的类。 - **`java.nio.charset.spi`**:定义了可用来实现 charset API ...
3. **`java.nio.channels.spi`**: 包含了用于实现通道(Channel)和选择器(Selector)的基础抽象类。 4. **`java.nio.charset`**: 处理字符集编码和解码的类。 5. **`java.nio.charset.spi`**: 提供了用于实现字符集...
- **通道(Channel)**:通道是NIO中的关键概念,它连接`Buffer`与外部实体,如文件或网络套接字,实现数据的读写。通道可以是阻塞的或非阻塞的,后者允许在没有数据可用时不会阻塞程序执行,而是立即返回,这在高并发...
JDK 1.4还引入了一系列新的APIs和特性,如`java.nio.channels.spi.AbstractInterruptibleChannel`,`java.nio.channels.spi.AbstractSelectableChannel`,`java.nio.charset.StandardCharsets`等,这些APIs丰富了...
import java.nio.channels.spi.*; import java.net.*; import java.util.*; /** * * @author Administrator * @version */ public class NBTest { /** Creates new NBTest */ public NBTest() { } ...
Selectors是Java NIO中的一个多路复用器,它允许单个线程处理多个Channel。使用Selectors可以让一个单独的线程来监视多个输入通道,一旦某个通道上发生了读写事件,该选择器就会通知相应的通道进行读写操作。这意味...
Java NIO还包含了一些扩展的包,如java.nio.channels.spi包,该包中定义了通道服务提供接口(SPI),用于自定义通道的实现。java.nio.charset包和java.nio.charset.spi包则提供字符集的实现和SPI,用于处理不同编码...
### Java NIO 学习 #### 一、Java NIO 的背景及意义 在Java早期版本(JDK 1.4之前),IO操作主要依赖于`java.io`包中的流式(stream-based)API,这类API是阻塞式的。虽然对于大多数日常应用场景而言,这种模型...
import java.nio.channels.DatagramChannel ; import com.github.alei121.rawsocketspi.RSSelectorProvider ; import com.github.alei121.rawsocketspi.RSSocketAddress ; // Create DatagramChannel and bind ...
* NIO的原理:程序员需要了解NIO的原理和组件,包括Channel、Buffer和Selector。 Java并发包 * Java并发包:程序员需要了解Java并发包,包括CountDownLatch和CyclicBarrier的区别和应用场景。 数据库 * 数据库...
- NIO(New IO):非阻塞IO模型,Channel、Buffer和Selector的使用。 - 文件操作:文件读写,文件复制,以及随机访问文件的方法。 7. Lambda表达式与函数式编程 - Lambda表达式的语法:理解其简洁的语法,以及...
- **Dubbo底层实现原理**:基于SPI服务发现机制,使用Netty作为通信框架。 - **服务治理**:包括服务注册与发现、负载均衡、容错机制等。 - **分布式事务**:如两阶段提交、三阶段提交等协议。 - **负载均衡算法**:...