最近在看netty源码,遇到一个问题一直没有想明白,而且又牵扯出了其他的问题。
在netty源码中通过NioWorker作为一个selector进行轮询事件,同时对每一个channel都有一个buffer预言者,预言下一次到达的buffer大小。
    private boolean read(SelectionKey k) {
        final SocketChannel ch = (SocketChannel) k.channel();
        final NioSocketChannel channel = (NioSocketChannel) k.attachment();        final ReceiveBufferSizePredictor predictor =
            channel.getConfig().getReceiveBufferSizePredictor();
        final int predictedRecvBufSize = predictor.nextReceiveBufferSize();        int ret = 0;
        int readBytes = 0;
        boolean failure = true;        ByteBuffer bb = recvBufferPool.acquire(predictedRecvBufSize);
        try {
            while ((ret = ch.read(bb)) > 0) {
                readBytes += ret;
                if (!bb.hasRemaining()) {
                    break;
                }
            }
            failure = false;
        } catch (ClosedChannelException e) {
            // Can happen, and does not need a user attention.
        } catch (Throwable t) {
            fireExceptionCaught(channel, t);
        }        if (readBytes > 0) {
            bb.flip();            final ChannelBufferFactory bufferFactory =
                channel.getConfig().getBufferFactory();
            final ChannelBuffer buffer = bufferFactory.getBuffer(readBytes);
            buffer.setBytes(0, bb);
            buffer.writerIndex(readBytes);            recvBufferPool.release(bb);            // Update the predictor.
            predictor.previousReceiveBufferSize(readBytes);            // Fire the event.
            fireMessageReceived(channel, buffer);
        } else {
            recvBufferPool.release(bb);
        }        if (ret < 0 || failure) {
            k.cancel(); // Some JDK implementations run into an infinite loop without this.
            close(channel, succeededFuture(channel));
            return false;
        }        return true;
    }
原始的预言大小为1024,那么当我直接向netty服务端发送一个2048大小的字符时,我发现它第一次select到了事件后先读取了1024,然后发现buffer没有空间了,就结束这次读,然后再轮询时,又出现了一个读事件,猜测是否selector在执行select时都会对每一个注册来的sk的channel进行检测,如果channel中还存在数据就会认为此时已准备好读,就会添加selectedkey呢?
看了一些sun.nio中的源码,不过还不是很清楚,求高人指点下,多谢。