Java NIO之Selector
仅用单个线程来处理多个Channels的好处是,只需要更少的线程来处理通道。事实上,可以只用一个线程处理所有的通道。对于操作系统来说,线程之间上下文切换的开销很大,而且每个线程都要占用系统的一些资源(如内存)。因此,使用的线程越少越好。
仅用单个线程来处理多个Channels的好处是,只需要更少的线程来处理通道。事实上,可以只用一个线程处理所有的通道。对于操作系统来说,线程之间上下文切换的开销很大,而且每个线程都要占用系统的一些资源(如内存)。因此,使用的线程越少越好。
虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Selector 构成了核心的API。其它组件,如Pipe和FileLock,只不过是与三个核心组件共同使用的工具类。因此,在概述中我将集中在这三个组件上。其它组件会在单独的章节中讲到。
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。仅用单个线程来处理多个Channels的好处是,只需要更少的线程来处理通道。事实上,可以只用一个线程处理所有的通道。对于操作系统来说,线程之间上下文切换的开销很大,而且每个线程都要占用系统的一些资源(如内存)。因此,使用的线程越少越好。
下面通过分析java nio的Buffer类的源代码来学习Buffer中的position、limit、capcity和marker几个标志位的变化。
在使用传统IO方式进行大文件复制时,效率很低。因为传统IO每次只复制一个字节,下面将会介绍如何使用java的NIO实现文件复制。java的NIO每次复制一个缓冲区到另一个文件,这个缓冲区大小有用户自己定义,因此效率要比传统IO好很多。
Java NIO(New Input/Ouput)是从JDK1.4开始引入的新技术,是一种高速的、面向块的数据输入/输出技术,它弥补了原有的流式I/O的不足。
理解NIO中的缓冲区(buffer),则首先了解缓冲区两个重要的缓冲区组件:状态变量和访问方法 (Accessor)。 状态变量是NIO缓存对象的"内部统计机制"的关键。每一个读/写操作都会改变缓冲区的状态。通过记录和跟踪这些变化,缓冲区就可能够内部地管理自己的资源。
读和写是I/O的基本过程。从一个通道中读取很简单:只需创建一个缓冲区,然后让通道将数据读到这个缓冲区中。写入也相当简单:创建一个缓冲区,用数据填充它,然后让通道用这些数据来执行写入操作。
通道是对原I/O包中的流的模拟。到任何目的地(或来自任何地方)的所有数据都必须通过一个Channel对象。一个Buffer实质上是一个容器对象。发送给一个通道的所有对象都必须首先放到缓冲区中;同样地,从通道中读取的任何数据都要读到缓冲区中。
Java的NIO(新的输入/输出)库是在JDK1.4中引入的。NI/O弥补了原来I/O的不足,它在标准Java代码中提供了高速的、面向块的 I/O。通过定义包含数据的类,以及通过以块的形式处理这些数据,NIO不用使用本地代码(如:C代码)就可以利用底层优化,这是原来的I/O包所无法做到的。