views:

184

answers:

3

Hello friends,

This question is about the fallouts of using SingleThreadExecutor (JDK 1.6). Related questions have been asked and answered in this forum before, but I believe the situation I am facing, is a bit different.

Various components of the application (let's call the components C1, C2, C3 etc.) generate (outbound) messages, mostly in response to messages (inbound) that they receive from other components. These outbound messages are kept in queues which are usually ArrayBlockingQueue instances - fairly standard practice perhaps. However, the outbound messages must be processed in the order they are added. I guess use of a SingleThreadExector is the obvious answer here. We end up having a 1:1 situation - one SingleThreadExecutor for one queue (which is dedicated to messages emanating from one component).

Now, the number of components (C1,C2,C3...) is unknown at a given moment. They will come into existence depending on the need of the users (and will be eventually disposed of too). We are talking about 200-300 such components at the peak load. Following the 1:1 design principle stated above, we are going to arrange for 200 SingleThreadExecutors. This is the source of my query here.

I am uncomfortable with the thought of having to create so many SingleThreadExecutors. I would rather try and use a pool of SingleThreadExecutors, if that makes sense and is plausible (any ready-made, seen-before classes/patterns?). I have read many posts on recommended use of SingleThreadExecutor here, but what about a pool of the same?

What do learned women and men here think? I would like to be directed, corrected or simply, admonished :-).

Warm regards

+1  A: 

If your requirement is that the messages be processed in the order that they're posted, then you want one and only one SingleThreadExecutor. If you have multiple executors, then messages will be processed out-of-order across the set of executors.

If messages need only be processed in the order that they're received for a single producer, then it makes sense to have one executor per producer. If you try pooling executors, then you're going to have to put a lot of work into ensuring affinity between producer and executor.

Since you indicate that your producers will have defined lifetimes, one thing that you have to ensure is that you properly shut down your executors when they're done.

kdgregory
Thanks. That 'lot of work' part in your reply was the source of my discomfiture. Even if I can manage to do, having 200 SingleThreadPoolExecutors may not be a good idea. What do you think?
a_philomath
My "lot of work" comment was actually a suggestion that the 200 executors is the *correct* way to go ... provided that you can't use a single executor. But only you can know the actual requirements.
kdgregory
A: 

Messaging and batch jobs is something that has been solved time and time again. I suggest not attempting to solve it again. Instead, look into Quartz, which maintains thread pools, persisting tasks in a database etc. Or, maybe even better look into JMS/ActiveMQ. But, at the very least look into Quartz, if you have not already. Oh, and Spring makes working with Quartz so much easier...

harschware
Quartz is surely worth a look. Thanks. JMS is too heavy for the kind of application I am involved with; deployment characteristics of the application are deterrents to use of Spring.
a_philomath
A: 

I don't see any problem there. Essentially you have independent queues and each has to be drained sequentially, one thread for each is a natural design. Anything else you can come up with are essentially the same. As an example, when Java NIO first came out, frameworks were written trying to take advantage of it and get away from the thread-per-request model. In the end some authors admitted that to provide a good programming model they are just reimplementing threading all over again.

irreputable
Thanks, but is this a good design to have a bunch of SingleThreadPoolExecutors (to the tune of 300 at the peak time) - that is the question. This arrangement certainly keeps matters much simple for me, but would you approve of that from (eventual) performance/scalability point of view? Many thanks for taking time to reply.
a_philomath
200 threads shouldn't be a problem for a single machine. if you want more robust and scalable solution, you need a distributed architecture, existing frameworks for such purposes should be looked at.
irreputable