Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Netty 4中阻塞操作异常的原因是什么?_Java_Netty - Fatal编程技术网

Java Netty 4中阻塞操作异常的原因是什么?

Java Netty 4中阻塞操作异常的原因是什么?,java,netty,Java,Netty,最近,我在netty4项目中发现了一些阻塞操作异常 有人说,当使用start netty的ServerBootstrap的sync()方法时,可能会导致死锁,因为sync()将调用wait()方法,而wait()中有一个名为“checkDeadLock”的方法 但我不这么认为。ServerBootstrap使用名为boosGroup的EventLoopGroup,Channel使用workerGroup来操作IO,我认为它们不会相互影响,它们有不同的EventExecutor 在我的实践中,死锁

最近,我在netty4项目中发现了一些
阻塞操作异常

有人说,当使用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,或者对状态使用回调