FileChannel无法设置为非阻塞模式的原因

最近两天看nio的时候发现一个问题,

Selector的创建

通过调用Selector.open()方法创建一个Selector,如下:

Selector selector = Selector.open();

向Selector注册通道

为了将Channel和Selector配合使用,必须将channel注册到selector上。通过SelectableChannel.register()方法来实现,如下:

channel.configureBlocking(false);
SelectionKey key = channel.register(selector,Selectionkey.OP_READ);

与Selector一起使用时,Channel必须处于非阻塞模式下。这意味着不能将FileChannel与Selector一起使用,因为FileChannel不能切换到非阻塞模式。而套接字通道都可以。

以上从Java NIO系列教程(六) Selector看到的内容

 

上面有一句话 FileChannel不能切换到非阻塞模式  我翻了好几个博客,发现大家都是将这句话写下了,没解释原因。我就自己记录一下原因

首先先 FileChannel 的部分源码

public abstract class FileChannel
    extends AbstractInterruptibleChannel
    implements SeekableByteChannel, GatheringByteChannel, ScatteringByteChannel
{
    /**
     * Initializes a new instance of this class.
     */
    protected FileChannel() { }

    ........
}

FileChannel继承自AbstractInterruptibleChannel

还有以一个抽象类继承了AbstractInterruptibleChannel,这个类是 SelectableChannel

代码如下

public abstract class SelectableChannel
    extends AbstractInterruptibleChannel
    implements Channel
{

    /**
     * Initializes a new instance of this class.
     */
    protected SelectableChannel() { }


    ......

    
        /**
     * Adjusts this channel's blocking mode.
     *
     * 

If this channel is registered with one or more selectors then an * attempt to place it into blocking mode will cause an {@link * IllegalBlockingModeException} to be thrown. * *

This method may be invoked at any time. The new blocking mode will * only affect I/O operations that are initiated after this method returns. * For some implementations this may require blocking until all pending I/O * operations are complete. * *

If this method is invoked while another invocation of this method or * of the {@link #register(Selector, int) register} method is in progress * then it will first block until the other operation is complete.

* * @param block If true then this channel will be placed in * blocking mode; if false then it will be placed * non-blocking mode * * @return This selectable channel * * @throws ClosedChannelException * If this channel is closed * * @throws IllegalBlockingModeException * If block is true and this channel is * registered with one or more selectors * * @throws IOException * If an I/O error occurs */ public abstract SelectableChannel configureBlocking(boolean block) throws IOException; ...... }

在SelectableChannel中有configureBlocking方法,

AbstractInterruptibleChannel中没有此方法,FileChannel类中也没有此方法。

所以从源码的角度分析FileChannel不能切换到非阻塞模式,这就是原因。

 

欢迎大家加群:835870546

大家可以一起交流学习!

你可能感兴趣的:(JAVA)