I am writing a program in Java. The picture is self-explanatory -
The main method spawns three threads. The SAX processor processes the input XML file, generates JAXB objects and puts them in guava cache. Guava cache is handled by another thread. Whenever any object comes into the cache, this thread notifies the third thread which is the MDL generator (it relates the similar JAXB objects, interconnects them and generates another XML file, called MDL). I have coded the following for the main class -
package test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainClass {
public static void main(String args[]) {
ExecutorService xMLService = Executors.newFixedThreadPool(1);
xMLService.execute(new XMLProcessor());
ExecutorService cacheService = Executors.newFixedThreadPool(1);
cacheService.execute(new CacheProcessor());
ExecutorService mdlService = Executors.newFixedThreadPool(1);
mdlService.execute(new MDLProcessor());
xMLService.shutdown();
cacheService.shutdown();
mDLService.shutdown();
}
}
But now I have doubts regarding how to pass objects between the threads and how to notify the MDL generator whenever a new object comes to the cache. In Java old threading model we could use notify(), but I want to use the current ExecutorService. And there are asynchronous callbacks. So I am wondering how to design this framework. How to pass objects and notify the threads? We are keeping the cache objects in HashMap and the CacheService thread needs to pass the key to the MDLService. So which pattern should I use?
How to pass objects and notify the threads? We are keeping the cache objects in HashMap and the CacheService thread needs to pass the key to the MDLService. So which pattern should I use?
Seems to me that you have 1 thread too many. The XML reading thread and the MDL writing make sense, but a thread to just put things into an in-memory cache seems to be too complicated. If the MDL generator needs to use the Guava cache then it should "own" the cache and stick things into it.
That leaves you with 1 input SAX processor thread and one output MDL generator thread. Good. To connect the two I would use a BlockingQueue
like the LinkedBlockingQueue
. You may or may not want to set a size limit on the queue depending on whether or not the reading is faster than the writing and how many records in your job.
So you main thread will create the BlockingQueue
and then pass it to both the input and output threads. The SAX input thread calls put()
on the queue and the MDL output thread calls take()
puts the object into the Guava cache and then does the MDL generation.
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With