Even though ServerSocketReader was using a ThreadPool, the pool was configure with 1 core thread and an unbounded queue. ThreadPool will then prefer to queue packets instead of creating new threads so in practice this means that we were only using 1 thread to process incoming packets.
New system properties:
xmpp.server.processing.core.threads (default 2)
xmpp.server.processing.max.threads (default 50)
xmpp.server.processing.queue (default 50)
This means that the server will use 2 threads to process queued packets. And when the queue is full then more threads (up to 50) will be created to process the queue. When the extra (> 2) threads are idle for 1 minute they will be destroyed.