You are right.. Thanks for the report and fix!
 However, the accepted AioSocketChannel's AsynchronousChannelGroup is identical to that of AioServerSocketChannel.  It means any async I/O events will be firstly handled by the parent AsyncChannelGroup and then forwarded to the child AsyncChannelGroup.  Do you see any degradation in performance?
 Nevermind.  AioEventLoop.execute() will try to avoid that problem using reflection. :-)

AIO server channel accepts channels onto server event loop group
When a parent `AioServerSocketChannel` accepts a new inbound connection, the child `AioSocketChannel` is created with the server event loop group instead of a separate child event loop group.

Forcing both parent and child channels onto the same event loop group is still functionally correct, but can lead to connection timeout due to starvation at high throughput.  The NIO transport keeps the parent and child event loop groups separate and does not suffer from starvation at high throughput.

transport/src/main/java/io/netty/channel/socket/aio/AioServerSocketChannel.java
transport/src/main/java/io/netty/channel/socket/aio/AioServerSocketChannel.java
diff --git a/transport/src/main/java/io/netty/channel/socket/aio/AioServerSocketChannel.java b/transport/src/main/java/io/netty/channel/socket/aio/AioServerSocketChannel.java
index d7eca8dc7a4..4a83008d7ba 100755
--- a/transport/src/main/java/io/netty/channel/socket/aio/AioServerSocketChannel.java
+++ b/transport/src/main/java/io/netty/channel/socket/aio/AioServerSocketChannel.java
@@ -40,6 +40,7 @@ public class AioServerSocketChannel extends AbstractAioChannel implements Server
     private static final InternalLogger logger =
             InternalLoggerFactory.getInstance(AioServerSocketChannel.class);
 
+    private final AioEventLoopGroup childGroup;
     private final AioServerSocketChannelConfig config;
     private boolean closed;
     private AtomicBoolean readSuspended = new AtomicBoolean();
@@ -60,9 +61,14 @@ private static AsynchronousServerSocketChannel newSocket(AsynchronousChannelGrou
         }
     }
 
-    public AioServerSocketChannel(AioEventLoopGroup eventLoop) {
-        super(null, null, eventLoop, newSocket(eventLoop.group));
-        config = new AioServerSocketChannelConfig(javaChannel());
+    public AioServerSocketChannel(AioEventLoopGroup group) {
+        this(group, group);
+    }
+
+    public AioServerSocketChannel(AioEventLoopGroup parentGroup, AioEventLoopGroup childGroup) {
+        super(null, null, parentGroup, newSocket(parentGroup.group));
+        this.childGroup = childGroup;
+        this.config = new AioServerSocketChannelConfig(javaChannel());
     }
 
     @Override
@@ -147,7 +153,7 @@ protected void completed0(AsynchronousSocketChannel ch, AioServerSocketChannel c
 
             // create the socket add it to the buffer and fire the event
             channel.pipeline().inboundMessageBuffer().add(
-                    new AioSocketChannel(channel, null, channel.group, ch));
+                    new AioSocketChannel(channel, null, channel.childGroup, ch));
             if (!channel.readSuspended.get()) {
                 channel.pipeline().fireInboundBufferUpdated();
             }
