DatagramChannel,阻塞模式和cpu

时间:2014-02-17 10:05:59

标签: java blocking nio2

我收到以下代码段:

datagramChannel = DatagramChannel
    .open(StandardProtocolFamily.INET).setOption(StandardSocketOptions.SO_REUSEADDR, true)
    .setOption(StandardSocketOptions.IP_MULTICAST_IF, networkInterface);
datagramChannel.configureBlocking(true);
datagramChannel.bind(new InetSocketAddress(filter.getType()
    .getPort(filter.getTimeFrameType())));
datagramChannel.join(group, networkInterface);
datagramChannel.receive(buffer);

此代码位于Callable中,我最多可创建12个Callable(12个线程),以检索来自12个不同端口的不同数据的多播数据包。它只能从网络上每隔3-8秒播放一次的信息中读取。

当连续汇集12个端口(等待信息,获取信息等等)时,它会占用我的一个CPU的100%。

使用JVisualVM分析执行情况,我发现90%的执行时间用于java.nio.channels.DatagramChannel#receive(),更准确地说是com.sun.nio.ch.DatagramChannelImpl#receiveIntoBuffer()

  1. 我不明白为什么阻塞模式吃了那么多CPU。

  2. 我已经阅读了一些关于使用Selector而非阻止模式的文章,但我真的不明白为什么while (true)Selector的消耗比阻止频道。

1 个答案:

答案 0 :(得分:1)

问题是你在没有选择器的情况下使用NIO。

没有Selector的NIO可以使用但是Channel.receive会不断尝试读取哪个会显示为一个线程的高CPU使用率。

有两种解决方案: -

  • 使用选择器检测是否有要读取的内容。仅当Selector指示有要读取的数据时才调用channel.receive
  • 使用java.net.DatagramSocket / DatagramPacket以阻塞模式发送/接收。