0

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

我不知道为什么会抛出这样的异常以及究竟是什么导致它发生。在此先感谢您的帮助,这个问题确实困扰着我。

4

1 回答 1

1

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

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

于 2013-05-19T11:18:40.370 回答