ClientBootstrap releaseExternalResources()抛出IllegalStateException

时间:2013-05-16 16:06:31

标签: java netty bootstrapping

我正在使用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."

我不知道为什么会抛出这样的异常以及究竟是什么导致它发生。在此先感谢任何帮助,这个问题真的让我烦恼。

1 个答案:

答案 0 :(得分:1)

错误消息告诉您不能从执行程序管理的线程调用releaseExternalResources,而执行程序本身由releaseExternalResources管理。它会导致死锁,因为releaseExternalResources正在尝试关闭执行程序,该执行程序在调用releaseExternalResources的线程返回之前不会返回(它不能)。

我猜你是从执行者管理的线程调用releaseExternalResources传递给OioClientSocketChannelFactory,可能来自处理程序内部。这不行。您需要从完全独立的线程中调用它。一种选择是阻止您的主应用程序线程,直到您准备好关闭,发出应用程序线程信号并让它在应用程序退出之前调用releaseExternalResources。

相关问题