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

代码如下

扫描二维码关注公众号,回复: 2520502 查看本文章
public abstract class SelectableChannel
    extends AbstractInterruptibleChannel
    implements Channel
{

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


    ......

    
        /**
     * Adjusts this channel's blocking mode.
     *
     * <p> 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.
     *
     * <p> 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.
     *
     * <p> 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. </p>
     *
     * @param  block  If <tt>true</tt> then this channel will be placed in
     *                blocking mode; if <tt>false</tt> then it will be placed
     *                non-blocking mode
     *
     * @return  This selectable channel
     *
     * @throws  ClosedChannelException
     *          If this channel is closed
     *
     * @throws  IllegalBlockingModeException
     *          If <tt>block</tt> is <tt>true</tt> 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不能切换到非阻塞模式,这就是原因。

猜你喜欢

转载自blog.csdn.net/King_flag/article/details/81359668