《JAVA NIO》Channel

3、通道

Channle主要分为两类:File操作对应的FIleChannel和Stream操作对应的socket的3个channe。

1、这3个channel都是抽象类。其具体实现在SPI里面。

2、这3个channel都是双向的,都实现了ByteChannel。

3、网络Channel可工作在非阻塞模式下,是可配置的FileChannel在NIO里面只能工作在阻塞模式下。

4、4个Channel的操作都是可中断的。可中断的语义如下

 

问题:stream操作除了socket还有其他的吧?例如串口等

       为什么FIleChannel不能工作在非阻塞模式下?

3.1.1打开通道

通道可以以多种方式创建。Socket 通道有可以直接创建新socket 通道的工厂方法。但是一个FileChannel 对象却只能通过在一个打开的RandomAccessFile、FileInputStream 或 FileOutputStream对象上调用getChannel( )方法来获取。您不能直接创建一个FileChannel 对象。File 和socket 通道会

SocketChannel sc = SocketChannel.open( );
sc.connect (new InetSocketAddress ("somehost", someport));
ServerSocketChannel ssc = ServerSocketChannel.open( );
ssc.socket( ).bind (new InetSocketAddress (somelocalport));
DatagramChannel dc = DatagramChannel.open( );
RandomAccessFile raf = new RandomAccessFile ("somefile", "r");
FileChannel fc = raf.getChannel( );

Reader和Writer不能用来产生Channel

3.1.2使用通道

1、Channel是针对于Byte操作的

2、ReadonluByteChannel和WritableByteChannel是单双工的,ByteChannle是全双工的。

3、每一个file和socket的channle都实现了ByteChannel,按理来说都应该是全双工的,socket的channel确实是全双工的,但是FileChannel则不一定。因为文件channel是和文件相关的,会受到文件的打开方式和文件的权限。

  我们知道,一个文件可以在不同的时候以不同的权限打开。从FileInputStream 对象的getChannel( )方法获取的FileChannel 对象是只读的,不过从接口声明的角度来看却是双   向的,因为FileChannel 实现ByteChannel 接口。在这样一个通道上调用write( )方法将抛出未经检查的NonWritableChannelException 异常,因为FileInputStream 对象     总是以read-only 的权限打开文件。

 4、通道可以以阻塞(blocking)或非阻塞(nonblocking)模式运行。非阻塞模式的通道􂉨远不会让调用的线程阻塞。请求的操作要么立即完成,要么返回一个结果表明未进行任        何操作。只有面向流的(stream-oriented)的通道,如sockets 和pipes 才能使用非阻塞式。

5、4 个channel都是可中断的。已验证,是的,不只close,read和write也是可中断的

3.1.3关闭通道

1、调用通道的close( )方法时,可能会导致在通道关闭底层I/O服务的过程中线程暂时阻塞,哪怕该通道处于非阻塞模式。通道关闭时的阻塞行为(如果有的话)是高度取决于操作系统或者文件系统的。在一个通道上多次调用close( )方法是没有坏处的,但如果第一个线程在close( )方法中阻塞,那么在它完成关闭通道之前,任何其他调用close( )方法都会阻塞。后续在该已关闭的通道上调用close( )不会产生任何操作,只会立即返回。

2、

3.3 FileChannel

   为什么FileChannel没有Stream IO那样的非阻塞模式?

   1、块IO系统调用时内核态首先会检查是否已经暂存了页,如果没有只能让磁盘控制器去copy,然后线程阻塞。

问题:内存映射文件如果大量页被缓存在磁盘,那缺页中断是否线

        程会阻塞,或者性能较差?

写IO因为只是将数据copy到内核态,然后磁盘器去写,那么线程应该不会阻塞吧?

   2、Stream IO的非阻塞有选择器搭配

FileChannel的API

position

3.3.2文件锁定

锁和文件相关,和线程,文件句柄无关

3.4内存映射文件

问题:directBuffer的原理是内存映射,写完数据然后又读数据,在磁盘还没写数据的时候可能buffer的数据就变化了,具体是怎么做的

    内存映射文件相对于直接内存有什么优势?

 

    2、内存映射文件应该会尽量加载很多的页到内存

内存映射文件的3种模式:

只读,读写,写时复制

内存映射文件的回收?

   full  gc

load(),isloaded(),force()

   load不能保证全部加载进内存,而且页也可能被移除内存。

force

问题:

一个文件既可以被读也可以被写吗?

         一个文件可以被同时读和写,所以文件锁很有用

.getChannel可以产生多少个channel

        相同的

 问题:FileChnanel和文件BIO的对比?

      1、FileChannel支持中断

      2、FileChannel缓冲区有什么优势?(和数组应该差不多吧)

     3、FileChannel无copy

     4、内存映射文件,可以极大的优化随机读。

问题:内存映射文件的优点

        1、零copy

        2、无系统调用

       3、数据可能更多的缓存在内存里(如果大量的数据依然存储在磁盘上,这时的性能怎么样?)

 

posted @ 2016-07-18 09:43  YDDMAX  阅读(836)  评论(0编辑  收藏  举报