Java Netty 4中阻塞操作异常的原因是什么?
最近,我在netty4项目中发现了一些Java Netty 4中阻塞操作异常的原因是什么?,java,netty,Java,Netty,最近,我在netty4项目中发现了一些阻塞操作异常 有人说,当使用start netty的ServerBootstrap的sync()方法时,可能会导致死锁,因为sync()将调用wait()方法,而wait()中有一个名为“checkDeadLock”的方法 但我不这么认为。ServerBootstrap使用名为boosGroup的EventLoopGroup,Channel使用workerGroup来操作IO,我认为它们不会相互影响,它们有不同的EventExecutor 在我的实践中,死锁
阻塞操作异常
有人说,当使用start netty的ServerBootstrap的sync()方法时,可能会导致死锁,因为sync()将调用wait()方法,而wait()中有一个名为“checkDeadLock”的方法
但我不这么认为。ServerBootstrap使用名为boosGroup的EventLoopGroup,Channel使用workerGroup来操作IO,我认为它们不会相互影响,它们有不同的EventExecutor
在我的实践中,死锁异常不会出现在Netty启动过程中,大多数情况下都发生在await writeAndFlush通道之后
分析源代码,checkDeadLock
,BlockingOperationException
当当前线程和执行线程相同时引发异常
我的项目代码是:
private void channelWrite(T message) {
boolean success = true;
boolean sent = true;
int timeout = 60;
try {
ChannelFuture cf = cxt.write(message);
cxt.flush();
if (sent) {
success = cf.await(timeout);
}
if (cf.isSuccess()) {
logger.debug("send success.");
}
Throwable cause = cf.cause();
if (cause != null) {
this.fireError(new PushException(cause));
}
} catch (LostConnectException e) {
this.fireError(new PushException(e));
} catch (Exception e) {
this.fireError(new PushException(e));
} catch (Throwable e) {
this.fireError(new PushException("Failed to send message“, e));
}
if (!success) {
this.fireError(new PushException("Failed to send message"));
}
}
我知道Netty的官员建议不要使用sync()或wait()方法,但我想知道什么情况会导致进程死锁,当前线程和执行线程是相同的。
我更改了我的项目代码
private void pushMessage0(T message) {
try {
ChannelFuture cf = cxt.writeAndFlush(message);
cf.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws PushException {
if (future.isSuccess()) {
logger.debug("send success.");
} else {
throw new PushException("Failed to send message.");
}
Throwable cause = future.cause();
if (cause != null) {
throw new PushException(cause);
}
}
});
} catch (LostConnectException e) {
this.fireError(new PushException(e));
} catch (Exception e) {
this.fireError(new PushException(e));
} catch (Throwable e) {
this.fireError(new PushException(e));
}
}
但是我面临一个新问题,我无法从ChannelHandlerListener获取pushException。如果在未来
上调用同步*
或等待*
时,netty将抛出BlockingOperationException,该线程与事件执行器
使用且与未来
绑定在一起。这通常是频道本身使用的EventLoop
。无法在IO线程中调用wait是可以理解的。然而,有两点。
1.如果在通道处理程序中调用下面的代码,则不会报告任何异常,因为在等待中对isDone的检查大部分时间返回true,因为您处于IO线程中,并且IO线程正在同步写入数据。调用wait时,数据已写入
ChannelPromise p = ctx.writeAndFlush(msg);
p.await()
如果在不同的EventExecutor组中添加处理程序,则无需进行此检查,因为该执行器是新创建的,并且与通道的IO执行器不同李>
你当然不能。你还没来得及看,就把自己扔了。涉及future.cause()
的代码应该在前面的else
块中,而不是在那里。您的pushMessage
抛出pushexception
在异步世界中不起作用,它应该为操作返回future,或者对状态使用回调