java selector wakeup_java – Selector.select()启动一个无限循环

我有一个最小的JMS提供程序,它通过UDP发送主题消息并通过TCP发送队列消息.

我使用单个选择器来处理UDP和TCP选择键(注册SocketChannels和DatagramChannels).

我的问题是:如果我只发送和接收UDP数据包,一切顺利,但一旦我开始在TCP套接字上写(使用Selector.wakeup()让选择器进行实际写入),选择器进入无限循环,返回一个空的选择键集,并吃掉100%的CPU.

主循环的代码(稍微简化)是:

public void run() {

while (!isInterrupted()) {

try {

selector.select();

} catch (final IOException ex) {

break;

}

final Iterator selKeys = selector.selectedKeys().iterator();

while (selKeys.hasNext()) {

final SelectionKey key = selKeys.next();

selKeys.remove();

if (key.isValid()) {

if (key.isReadable()) {

this.read(key);

}

if (key.isConnectable()) {

this.connect(key);

}

if (key.isAcceptable()) {

this.accept(key);

}

if (key.isWritable()) {

this.write(key);

key.cancel();

}

}

}

synchronized(waitingToWrite) {

for (final SelectableChannel channel: waitingToWrite) {

try {

channel.register(selector, SelectionKey.OP_WRITE);

} catch (ClosedChannelException ex) {

// TODO: reopen

}

}

waitingToWrite.clear();

}

}

}

而对于UDP发送(TCP发送类似):

public void udpSend(final String xmlString) throws IOException {

synchronized(outbox) {

outbox.add(xmlString);

}

synchronized(waitingToWrite) {

waitingToWrite.add(dataOutChannel);

}

selector.wakeup();

}

那么,这里有什么问题?我应该使用2个不同的选择器来处理UDP和TCP数据包吗?

解决方法:

我建议你检查select()方法的返回值.

try {

if(selector.select() == 0) continue;

} catch (final IOException ex) {

break;

}

您是否尝试调试以查看循环的位置?

编辑:

>我建议不要在迭代器上调用“remove()”,而是在迭代它们之后调用selectedKeys.clear().迭代器的实现可能不会从底层集中删除它.

>检查您是否在连接的通道上注册OP_CONNECT.

标签:udp,java,tcp,nio,socketchannel

来源: https://codeday.me/bug/20190630/1341242.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值