http://www.52im.net/thread-2640-1-1.html
学习2
学习3
这里是引用举个生活中简单的例子,你妈妈让你烧水,小时候你比较笨啊,在哪里傻等着水开(同步阻塞)。等你稍微再长大一点,你知道每次烧水的空隙可以去干点其他事,然后只需要时不时来看看水开了没有(同步非阻塞)。后来,你们家用上了水开了会发出声音的壶,这样你就只需要听到响声后就知道水开了,在这期间你可以随便干自己的事情,你需要去倒水了(异步非阻塞)。
服务端注册到selector上 然后每一个selectionKey对应着一个I/O事件
当客户端连接上之后 将客户端也注册到selector
NIO 弥补了原来的 I/O 的不足,它在标准 Java 代码中提供了高速的、面向块的 I/O,块 I/O 的效率可以比流 I/O 高许多。
NIO 将最耗时的 I/O 操作(即填充和提取缓冲区)转移回操作系统,因而可以极大地提高速度。
面向流的 I/O 通常相当慢
- 在面向流的 I/O 中,您将数据直接写入或者将数据直接读到 Stream 对象中。
- 在 NIO 库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的。在写入数据时,它是写入到缓冲区中的。任何时候访问 NIO 中的数据,您都是将它放到缓冲区中。Buffer 是一个对象, 它包含一些
要写入
或者刚读出
的数据。最常用的缓冲区类型是ByteBuffer
。
-
通道与流的不同之处在于通道是双向的。而流只是在一个方向上移动(一个流必须是 InputStream 或者 OutputStream 的子类), 而 通道 可以用于读、写或者同时用于读写。
-
因为它们是双向的,所以通道可以比流更好地反映底层操作系统的真实情况。特别是在 UNIX 模型中,底层操作系统通道是双向的。
SELECTOR
我们将对不同的通道对象(ServerSocketChannel / SocketChannel)调用 register() 方法,以便注册我们对这些对象中发生的 I/O 事件的兴趣。
将新打开的 ServerSocketChannel 注册到 Selector上。
为此我们使用 ServerSocketChannel.register() 方法,
SelectionKey key = ssc.register( selector, SelectionKey.OP_ACCEPT );
register() 的第一个参数总是这个 Selector。
第二个参数是 OP_ACCEPT,这里它指定我们想要监听 accept 事件,也就是在新的连接建立时所发生的事件。这是适用于 ServerSocketChannel 的唯一事件类型
。
请注意对 register() 的调用的返回值。 SelectionKey 代表这个通道(ServerSocketChannel )在此 Selector 上的这个注册。当某个 Selector 通知您某个传入事件时,它是通过提供对应于该事件的 SelectionKey 来进行的。SelectionKey 还可以用于取消通道的注册。
是将新连接的 SocketChannel 配置为非阻塞的。而且由于接受这个连接的目的是为了读取来自套接字的数据,所以我们还必须将 SocketChannel 注册到 Selector上,如下所示:
一组 SelectionKey。每个键代表一个 I/O 事件。我们处理事件,从选定的键集中删除 SelectionKey,然后返回主循环的顶部。
bio阻塞是说 IO阻塞 不是网络阻塞
NIO的同步也指的是IO的同步