java nio 死循环_Java NIO的一些总结

channel在linux系统中也是一种文件,

Channels are analogous to "file descriptors" found in Unix-like operating systems.

故一个Selector管理的channel也有数目限制, 若超过限制会报如下错误:

java.io.IOException: Too many open files

at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)

at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:241)

2. 使用java IO(即使用socket.getOutputStream())往服务端写数据时,若发生了网络超时, 仍能成功写入,只不过是写到了OS的Send-Q中。如下所示:

$ netstat -nat

Active Internet connections (servers and established)

Proto Recv-Q Send-Q Local Address           Foreign Address         State

......

$ netstat -nat|grep 9001

tcp6      30     60 127.0.0.1:57256         127.0.0.1:9001          ESTABLISHED

$ netstat -nat|grep 9001 #第三列send_q由60增加为70了

tcp6      30     70 127.0.0.1:57256         127.0.0.1:9001          ESTABLISHED

...

$ netstat -nat|grep 9001

tcp6      30    520 127.0.0.1:57256         127.0.0.1:9001          ESTABLISHED

#等网络恢复正常后 会被服务端一次性接收

$ netstat -nat|grep 9001

tcp6     615      0 127.0.0.1:57256         127.0.0.1:9001          ESTABLISHED

等网络恢复正常时, 会被服务端一次性接收到之前客户端超时期间累积的数据。这种情况下没有办法设置写超时。

但若使用NIO的话, 注册了socketChannel写事件的话,如下所示:

scChannel.register(selector, SelectionKey.OP_WRITE);

若网络超时的话, selector是不会选择该channel的,若客户端仅有该channel的话,会阻塞在selector.select()中,如下所示:

sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)

sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)

sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79)

sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87)

- locked sun.nio.ch.Util$2@e4f15c3

- locked java.util.Collections$UnmodifiableSet@6a1dbc8b

- locked sun.nio.ch.EPollSelectorImpl@4645801a

sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98)

sun.nio.ch.SelectorImpl.select(SelectorImpl.java:102)

故也就不会往服务端写数据了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值