NIO Channel 管道
Java NIO的通道类似流,但又有些不同:
- 既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。
- 通道可以异步地读写。
- 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。
正如上面所说,从通道读取数据到缓冲区,从缓冲区写入数据到通道。
Channel的实现
这些是Java NIO中最重要的通道的实现:
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
FileChannel 从文件中读写数据。
DatagramChannel 能通过UDP读写网络中的数据。
SocketChannel 能通过TCP读写网络中的数据。
ServerSocketChannel可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。
多数情况下,通道与操作系统的文件描述符(File Descriptor)和文件句柄(File Handle)有着一对一的关系(通道比文件描述符更广义)。
Channel接口:
public interface Channel
{
public boolean isOpen( );
public void close( ) throws IOException;
}
与缓冲区不同,通道API主要由接口指定。不同的操作系统上通道实现(Channel Implementation)会有根本性的差异,所以通道API仅仅描述了可以做什么。因此很自然地,通道实现经常使用操作系统的本地代码。通道接口允许您以一种受控且可移植的方式来访问底层的I/O服务。
InterruptibleChannel接口:
InterruptibleChannel是一个标记接口,当被通道使用时可以标示该通道是可以中断的(Interruptible)。如果连接可中断通道的线程被中断,那么该通道会以特别的方式工作。
两个对应的核心抽象类:
这两个类是AbstractInterruptibleChannel和AbstractSelectableChannel,它们分别为可中断的(interruptible)和可选择的(selectable)的通道实现提供所需的常用方法。尽管描述通道行为的接口都是在java.nio.channels包中定义的,不过具体的通道实现却都是从java.nio.channels.spi中的类引申来的。这使得他们可以访问受保护的方法,而这些方法普通的通道用户永远都不会调用。
获取管道的集中常见操作:
ServerSocketChannel ssc = ServerSocketChannel.open( );
ssc.socket( ).bind (new InetSocketAddress (8080)); SocketChannel sc = SocketChannel.open( );
sc.connect (new InetSocketAddress("localhost", 8080)); DatagramChannel dc = DatagramChannel.open( ); RandomAccessFile raf = new RandomAccessFile ("E:\\JcloudMyProject\\blogcode\\src\\main\\java\\heapStark\\blogCode\\nio\\Main.java", "r");
FileChannel fc = raf.getChannel( );
//Socket 无法产生Channel
Socket socket = new Socket();
socket.connect( new InetSocketAddress("localhost",8080));
assert (socket.getChannel()==null);
Socket类也有新的getChannel( )方法。这些方法虽然能返回一个相应的socket通道对象,但它们却并非新通道的来源,RandomAccessFile.getChannel( )方法才是。只有在已经有通道存在的时候,Socket类的getChannel( )方法才返回与一个socket关联的通道否则返回空。
关闭通道:
与缓冲区不同,通道不能被重复使用。一个打开的通道即代表与一个特定I/O服务的特定连接并封装该连接的状态。当通道关闭时,那个连接会丢失,然后通道将不再连接任何东西。调用通道的close( )方法时,可能会导致在通道关闭底层I/O服务的过程中线程暂时阻塞,哪怕该通道处于非阻塞模式。通道关闭时的阻塞行为(如果有的话)是高度取决于操作系统或者文件系统的。在一个通道上多次调用close( )方法是没有坏处的,但是如果第一个线程在close( )方法中阻塞,那么在它完成关闭通道之前,任何其他调用close( )方法都会阻塞。后续在该已关闭的通道上调用close( )不会产生任何操作,只会立即返回。尝试进行任何需要通道处于开放状态作为前提的操作,如读、写等都会导致ClosedChannelException异常。
ByteChannel继承关系:

ByteChannel接口本身并不定义新的API方法,它是一种用来聚集它自己以一个新名称继承的多个接口的便捷接口。根据定义,实现ByteChannel接口的通道会同时实现ReadableByteChannel 和WritableByteChannel两个接口,所以此类通道是双向的。这是简化类定义的语法糖(syntactic sugar)。
阻塞(blocking)或非阻塞(nonblocking):
通道可以以阻塞(blocking)或非阻塞(nonblocking)模式运行。非阻塞模式的通道永远不会让调用的线程休眠。请求的操作要么立即完成,要么返回一个结果表明未进行任何操作。只有面向流的(stream-oriented)的通道,如sockets和pipes才能使用非阻塞模式。SocketChannel通道类从SelectableChannel引申而来。从SelectableChannel引申而来的类可以和支持有条件的选择(readiness selectio)的选择器(Selectors)一起使用。将非阻塞I/O和选择器组合起来可以使您的程序利用多路复用I/O(multiplexed I/O)。
- InterruptibleChannel接口,标记接口
如果一个线程在一个InterruptibleChannel通道上被阻塞并且同时被中断(由调用该被阻塞线程的interrupt( )方法的另一个线程中断),那么该通道将被关闭,
该被阻塞线程也会产生一个ClosedByInterruptException异常。此外,假如一个线程的interrupt status被设置并且该线程试图访问一个通道,
那么这个通道将立即被关闭,同时将抛出相同的ClosedByInterruptException异常。线程的interrupt status在线程的interrupt( )方法被调用时会被设置。
我们可以使用isInterrupted( )来测试某个线程当前的interrupt status。当前线程的interrupt status可以通过调用静态的Thread.interrupted( )方法清除。
仅仅因为休眠在其上的线程被中断就关闭通道,这看起来似乎过于苛刻了。不过这却是NIO架构师们所做出的明确的设计决定。经验表明,想要在所有的操作系统上一致而可靠地处理被中断的I/O操作是不可能的。“在全部平台上提供确定的通道行为”这一需求导致了“当I/O操作被中断时总是关闭通道”这一设计选择。这个选择被认为是可接受的,因为大部分时候一个线程被中断就是希望以此来关闭通道。java.nio包中强制使用此行为来避免因操作系统独特性而导致的困境,因为该困境对I/O区域而言是极其危险的。这也是为增强健壮性(robustness)而采用的一种经典的权衡。可中断的通道也是可以异步关闭的。实现InterruptibleChannel接口的通道可以在任何时候被关闭,即使有另一个被阻塞的线程在等待该通道上的一个I/O操作完成。当一个通道被关闭时,休眠在该通道上的所有线程都将被唤醒并接收到一个AsynchronousCloseException异常。接着通道就被关闭并将不再可用。
NIO Channel 管道的更多相关文章
- Java NIO Channel和Buffer
Java NIO Channel和Buffer @author ixenos Channel和Buffer的关系 1.NIO速度的提高来自于所使用的结构更接近于OS执行I/O的方式:通道和缓冲器: 2 ...
- Java NIO Channel之FileChannel [ 转载 ]
Java NIO Channel之FileChannel [ 转载 ] @author zachary.guo 对于文件 I/O,最强大之处在于异步 I/O(asynchronous I/O),它允许 ...
- Java NIO Channel通道
原文链接:http://tutorials.jenkov.com/java-nio/channels.html Java NIO Channel通道和流非常相似,主要有以下几点区别: 通道可以读也可以 ...
- (三:NIO系列) Java NIO Channel
出处: Java NIO Channel 1.1. Java NIO Channel的特点 和老的OIO相比,通道和NIO流(非阻塞IO)主要有以下几点区别: (1)OIO流一般来说是单向的(只能读或 ...
- NIO Channel Scatter/Gather 管道Pipe类
通道提供了一种被称为Scatter/Gather的重要新功能(有时也被称为矢量I/O).Scatter/Gather是一个简单却强大的概念,它是指在多个缓冲区上实现一个简单的I/O操作.对于一个wri ...
- NIO之管道 (Pipe)
Java NIO 管道是2个线程之间的单向数据连接.Pipe有一个source通道和一个sink通道.数据会被写到sink通道,从source通道读取. 代码使用示例: public static v ...
- [翻译] java NIO Channel
原文地址:http://tutorials.jenkov.com/java-nio/channels.html JAVA NIO channels和流的概念很像,下面是他们的一些区别: 你可以对cha ...
- Java NIO Channel to Channel Transfers通道传输接口
原文链接:http://tutorials.jenkov.com/java-nio/channel-to-channel-transfers.html 在Java NIO中如果一个channel是Fi ...
- NIO Channel和Buffer
Java NIO 由以下几个核心部分组成: Buffer Channel Selector 传统的IO操作面向数据流,意味着每次从流中读一个或多个字节,直至完成,数据没有被缓存在任何地方.NIO操作面 ...
随机推荐
- 【面试突击】- sql语句的优化分析
开门见山,问题所在 原文地址:http://www.cnblogs.com/knowledgesea/p/3686105.html sql语句性能达不到你的要求,执行效率让你忍无可忍,一般会时下面几种 ...
- 面试总结之Data Science
数据科学家面试如何准备? https://mp.weixin.qq.com/s/uFJ58az8WRyaXT2nibK02g 2020 年算法 / 数据分析面试数学考点梳理 https://mp.we ...
- Nginx 反向代理Tomcat服务器获取真实IP问题
1.nginx.conf 配置 修改 Server location配置 增加 proxy_set_header X-Real-IP $remote_addr; #保留代理之前的真实客户端ip pro ...
- npm 安装、卸载 模块或包的命令(转载)
npm安装卸载命令 来源:https://www.jianshu.com/p/e6ee00ea03cd npm安装模块 [npm install xxx]利用 npm 安装xxx模块到当前命令行所在目 ...
- Java多线程 常见问题整理
线程 什么是线程 线程是指程序在执行过程中,能够执行程序代码的一个执行单元. 线程和进程的区别 线程:一段程序执行过程中的一个执行单元,各个线程之间共享程序的内存空间以及一些进程级的资源,各线程拥有自 ...
- appium 设备信息字典(desired_caps)
操作系统类型.操作系统版本.设备名称.要操作的APP应用的包名.activity名称desired_caps = { "platformName":"Android&qu ...
- MySQL DDL--MySQL 5.7版本Online DDL操作
主键索引维护 1.新增主键索引 ## 可以使用ALGORITHM=INPLACE+LOCK=NONE方式,操作期间允许读写. ALTER TABLE tb001 ADD PRIMARY KEY (ID ...
- 申请软件著作权,wps显示代码行号功能
申请软件著作权时,要提交代码. 格式要求,每页不少于50行,怎么设置格式,保障每页至少50行呢? 选择[页面布局]---[行号]--[每页重编行号]即可显示出来,根据显示出来的行号,调整行距等格式即可 ...
- 【Docker】docker的安装和常用命令
一.docker安装和启动 1.yum 命令 yum install docker 2.docker启动命令 sudo systemctl start docker 二.docker常用命令 dock ...
- class Pagination(object)分页源码
class Pagination(object): def init(self, current_page, all_count, per_page_num=10, pager_count=11): ...