简体   繁体   English

ClientBootstrap releaseExternalResources()引发IllegalStateException

[英]ClientBootstrap releaseExternalResources() throws an IllegalStateException

I am using netty to connect and disconnect. 我正在使用netty连接和断开连接。 But I get an exception when I try to disconnect, and I can't quite understand what causes it. 但是,当我尝试断开连接时会遇到异常,我无法完全理解是什么原因造成的。

I have a global: 我有一个全球性的:

private ClientBootstrap bootstrap_;

When I try to connect I perform the following: 当我尝试连接时,请执行以下操作:

First initialization: 第一次初始化:

ChannelFactory channelFactory = null;
channelFactory = new OioClientSocketChannelFactory(Executors.newCachedThreadPool());
bootstrap_ = new ClientBootstrap(channelFactory);

Followed by: 其次是:

    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);

And execute: 并执行:

    bootstrap_.connect(addr);

Which does return success. 确实返回成功。

Shortly after I close all the channels and try executing: 关闭所有通道并尝试执行后不久:

bootstrap_.releaseExternalResources();

to stop the connection, and it returns an IllegalStateException thrown by ExecutorUtil.java 停止连接,并返回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."

I have no idea why such an exception would be thrown and what exactly causes it to happen. 我不知道为什么会抛出这样的异常以及到底是什么导致了这种异常的发生。 Thanks in advance to any help, this issue is really bugging me. 在此先感谢您的帮助,此问题确实困扰着我。

The error message is telling you that you cannot call releaseExternalResources from a thread managed by an executor which, in itself, is managed by releaseExternalResources. 该错误消息告诉您,您不能从由执行者管理的线程中调用releaseExternalResources,该执行者本身由releaseExternalResources管理。 It results in a deadlock because releaseExternalResources is trying to shutdown the executor which won't return until the thread that has called releaseExternalResources returns (which it can't). 这会导致死锁,因为releaseExternalResources试图关闭执行程序,该执行程序要等到调用releaseExternalResources的线程返回(不能这样做)后才会返回。

I would guess that you're calling releaseExternalResources from a thread managed by the executor passed to OioClientSocketChannelFactory, possibly from within a handler. 我猜想您是从传递给OioClientSocketChannelFactory的执行程序管理的线程中调用releaseExternalResources的,可能是从处理程序中调用的。 This won't work. 这行不通。 You need to call it from a completely separate thread. 您需要从完全独立的线程中调用它。 One option is to block your main application thread until you're ready to shutdown, signal the application thread and have it call releaseExternalResources just before your application exits. 一种选择是阻塞主应用程序线程,直到您准备关闭时,向应用程序线程发出信号,并在应用程序退出之前让它调用releaseExternalResources。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM