Thread pooling in AIO/

Alan Bateman Alan.Bateman at Sun.COM
Thu Dec 18 03:58:26 PST 2008


Nord, James wrote:
> :
> Sorry I missused the word "default". I was using the following:
> 	pool = Executors.newCachedThreadPool();
> 	asynchronousChannelGroup =
> AsynchronousChannelGroup.withCachedThreadPool(pool, 1);
>
> This is 100 unique sockets with one multicast group per socket.
>
> (we are currently stressing the test with 5Mbit/s per multicast group)
>
> However we just re ran with the actual default channel group by using
> AsynchronousDatagramChannel.open()
> And it creates even more threads!!
>   
I haven't had cycles yet to swap in a replacement for the 
AsynchronousDatagramChannel implementation yet. The implementation that 
is there now is using a simple task per I/O operation. It needs to be 
replaced so that it uses overlapped I/O and the completion port 
mechanism like has already been done for the other network channels. The 
reason for the current simple implementation is to allow for feedback 
and test development. Although simple it isn't too bad as the number of 
UDP sockets is typically very small (using 100+ UDP ports is probably a 
lot more than average but still not a problem).

The reason you are seeing slightly more threads in the default group is 
that it tries to deliver good performance and at the same time 
potentially serve many masters. It does this by dedicating a few threads 
to the I/O port and then creating threads on demand as required. As 
AsynchronousDatagramChannel is simply submitting tasks to the thread 
pool it means the I/O threads are never used (but you see them in the 
thread dump).

Although the AsynchronousDatagramChannel is simple I wouldn't expect the 
performance to be too bad. Is it keeping up with the multicast load or 
are you seeing packet loss? I recall you were trying out the multicast 
support in DatagramChannel so I'm curious if this was the same load.

> :
> But that is my point - you have to supply the pool (via the executor)
> *and also* to the AsynchronousChannelGroup.
>
> E.g. for a fixed pool you need the following:
> 	ExecutorService executor = Executors.newFixedThreadPool(8);
> 	AsynchronousChannelGroup group =
> AsynchronousChannelGroup.withFixedThreadPool(executor, 8);		
>
> And for a cached pool you need:
> 	ExecutorService executor = Executors.newCachedThreadPool();
> 	AsynchronousChannelGroup group =
> AsynchronousChannelGroup.withCachedThreadPool(executor, 4);	
>
>
> Why don't we just have
> 	ExecutorService executor = // whatever executor type you want /
> fixed cached etc...
> 	AsynchronousChannelGroup group =
> AsynchronousChannelGroup.withThreadPool(executor);
>   
Others have also commented on this so there is a 
withThreadPool(executor) in for the next build. It's identical to 
withCachedThreadPool(executor,0) as this method can be invoked with any 
executor service.

> Does the group really care if its fixed or cached - doesn't it just want
> something to do some work?
>   
This page attempts to explain it:
  http://openjdk.java.net/projects/nio/resources/AsynchronousIo.html

-Alan.




More information about the nio-discuss mailing list