java.nio DatagramChannel非阻塞模式..你还要阻塞吗?

时间:2013-06-14 12:55:17

标签: java scala asynchronous nonblocking nio2

我一直在研究java.nio的异步功能,到目前为止,我是AsynchronousByteChannel类的粉丝,因为它允许我为每个读或写操作提供完成回调。这适用于scala的Future类。

现在我正在尝试异步地与DatagramChannel进行交互。 (作为好奇心,我正在尝试实现自己的torrent客户端,有些跟踪器使用UDP。)

我现在的目标是找到一种方法来调整当前readwrite方法的原始签名......

def write(src: ByteBuffer): Int
def read(dest: ByteBuffer): Int

以scala-futures为导向的签名,如......

def write(src: ByteBuffer): scala.concurrent.Future[Int]
def read(dest: ByteBuffer): scala.concurrent.Future[Int]

查看API并在线查找示例,找到了前往Selector课程的方法。据我所知,这就是我需要用来使DatagramChannel成为“非阻塞”的东西,但我看到三种似乎相关的方法:

select() - blocks until a selection is ready
select(timeout) - blocks until either a selection is ready or timeout is reached
selectNow - doesn't block, but is useless if called before a selection is ready

所以看来我对“非阻塞”的选择要么是阻止(wtf?),要么占用一个运行繁忙循环的线程,该循环重复调用其中一个select方法。这是我的问题。

有没有办法使用DatagramChannel来实现真正的非阻塞IO?如果不是,那么处理(读取'最小化')实际阻塞的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

利用专用的选择器线程根本不是问题。首先,这是不可避免的。其次,AsynchronousByteChannel实现也使用底层的后台线程。

至于使用Selector的最佳方式,我相信我在SelectorThread实现中找到了一个(注意它仍然在“work”分支中)。我没有尝试使用DatagramChannel,但它应该工作:只需像AsyncSocketChannel1一样实现AsyncDatagramChannel。