我正在使用netty进行连接和断开连接。但是当我尝试断开连接时出现异常,我无法理解导致它的原因。
我有一个全球性的:
private ClientBootstrap bootstrap_;
当我尝试连接时,我执行以下操作:
首次初始化:
ChannelFactory channelFactory = null;
channelFactory = new OioClientSocketChannelFactory(Executors.newCachedThreadPool());
bootstrap_ = new ClientBootstrap(channelFactory);
其次是:
bootstrap_.setPipelineFactory(() -> {
ChannelPipeline pipeline = Channels.pipeline();
// SOME CODE
});
bootstrap_.setOption("remoteAddress", addr);
bootstrap_.setOption("tcpNoDelay", true);
bootstrap_.setOption("keepAlive", true);
bootstrap_.setOption("configureBlocking", false);
bootstrap_.setOption("connectTimeoutMillis", 5000);
执行:
bootstrap_.connect(addr);
哪会成功。
关闭所有频道并尝试执行后不久:
bootstrap_.releaseExternalResources();
停止连接,并返回ExecutorUtil.java抛出的IllegalStateException
"An Executor cannot be shut down from the thread " +
"acquired from itself. Please make sure you are " +
"not calling releaseExternalResources() from an " +
"I/O worker thread."
我不知道为什么会抛出这样的异常以及究竟是什么导致它发生。在此先感谢任何帮助,这个问题真的让我烦恼。
答案 0 :(得分:1)
错误消息告诉您不能从执行程序管理的线程调用releaseExternalResources,而执行程序本身由releaseExternalResources管理。它会导致死锁,因为releaseExternalResources正在尝试关闭执行程序,该执行程序在调用releaseExternalResources的线程返回之前不会返回(它不能)。
我猜你是从执行者管理的线程调用releaseExternalResources传递给OioClientSocketChannelFactory,可能来自处理程序内部。这不行。您需要从完全独立的线程中调用它。一种选择是阻止您的主应用程序线程,直到您准备好关闭,发出应用程序线程信号并让它在应用程序退出之前调用releaseExternalResources。