diff --git a/common/src/main/java/io/netty/util/concurrent/SingleThreadEventExecutor.java b/common/src/main/java/io/netty/util/concurrent/SingleThreadEventExecutor.java index 994b961729..f11cc2ea62 100644 --- a/common/src/main/java/io/netty/util/concurrent/SingleThreadEventExecutor.java +++ b/common/src/main/java/io/netty/util/concurrent/SingleThreadEventExecutor.java @@ -911,6 +911,12 @@ public abstract class SingleThreadEventExecutor extends AbstractScheduledEventEx try { cleanup(); } finally { + // Lets remove all FastThreadLocals for the Thread as we are about to terminate and notify + // the future. The user may block on the future and once it unblocks the JVM may terminate + // and start unloading classes. + // See https://github.com/netty/netty/issues/6596. + FastThreadLocal.removeAll(); + STATE_UPDATER.set(SingleThreadEventExecutor.this, ST_TERMINATED); threadLock.release(); if (!taskQueue.isEmpty()) { @@ -919,7 +925,6 @@ public abstract class SingleThreadEventExecutor extends AbstractScheduledEventEx "non-empty task queue (" + taskQueue.size() + ')'); } } - terminationFuture.setSuccess(null); } }