我正在编写一个非阻塞客户端,它使用选择器SelectionKey.OP_READ
和selector.select()
调用从网络套接字读取数据。阅读部分的处理方式如下:
if (selectionKey.isReadable()) {
int len = inChannel.read(buf);
System.out.println(len);
. . .
}
我看到的问题是随着下载的进行,读取大小(len
)逐渐退化:
1290
1290
1290
480
318
28
28
28
28
28
28
28
28
28
28
28
28
28
有谁知道这是为什么以及如何改进它?当然,它按原样工作,但我需要减少cpu开销,因此最好处理大块而不是小块。添加小睡眠(20ms)会有所帮助,但显然会限制可扩展性,因为我需要同时处理数千个流。
答案 0 :(得分:0)
回答我自己的问题......
没关系;我没有正确使用缓冲区。从缓冲区读取后忘记compact()
调用。
if (selectionKey.isReadable()) {
int len = inChannel.read(buf);
System.out.println(len);
. . .
buf.flip();
// ... read from buf ...
buf.compact();
}
显然缓冲区不是循环的;即使缓冲区为空,也必须在下次使用前重置位置和限制。