With NIO you could do everything from one thread, that is what I am doing. I also have a LinkedList of outgoing packets which at any time in the game frame can be added to, my send method (called once per frame) simply grabs the first few on the list to send each frame.
Don’t forget that with SocketBuffer, it’s just a stream of bytes. There’s no packet start and packet end markers like there were with Object[Output/Input]Stream. So you need to first send the number of bytes, then keep waiting on the other end until all the bytes have arrived, then the game packet can be processed. ByteBuffer.compact() is useful for when you only have half a packet in the buffer, but need to get more space so the rest can be recieved (hopefully though, your game packet is sent in one transmittion and half/packets are fairly rare – they would certainly be more common with laggy connections over the internet).
I found the Java NIO book useful, and I read it online though Safari.
Will.