Asynchronous Execution Wrapper

Posted by - raja 2008/02/10 20:18:50

Asynchronously executing a "Fire & Forget" task that implements any business interface (not Runnable etc.) in Java

With the advent of Java 5 , asynchronous execution has become an easy thing to code. One has to be just grab hold of an ExecutorService from the java.util.concurrent library and start passing it a runnable. The only problem with this is that our class has to implement the Runnable interface which is not often desirable.

My intention was to open the doors of this to every interface - not just Runnable.  I wanted to create a class that is capable of implementing any interface. So let us say I have a Foo interface. There are a few criteria around Foo.

  • A method of Foo either returns a void.

OR

  • returns a meaningful value but in the process does something to expedite future calls (such as caching the result of the current call)

 Basically, Foo is a "Fire & Forget" interface.

Let us say I have a FooImpl which implements Foo but does so synchronously.

I want to automatically make FooImpl asynchronous. I want to write a class that wraps FooImpl. This class should implement Foo during runtime. This way, the consumer of Foo does not know that it is dealing with any asynchronous stuff. It merely calls Foo methods and voila! they get executed asynchronously and none the wiser for it. I wanted to use JDK proxies to create a runtime implementation of Foo. So combining these two thoughts, I created a simple class AsyncExecutor.

This class implements the InvocationHandler to take advantage of the java reflection interface proxy. Separate asynchronous proxies are created for every tuple of Interface, Implementation to wrap and executor service. Notice how the static method's signature uses java generics to convey its meaning precisely.

This class can be very useful for imbibing asynchronous behavior to synchronous classes.

Blog Comments (4)

Stefan, 2012-09-17 14:04:43

Hi, can you give an example of how to call the AsyncExecutor class , assuming you have a Foo interface and FooImpl class ? I must be doing something wrong but can't seem to get it. Thx.

Raja, 2012-09-17 19:05:51

"Hello Stefan My bad. I must have been clearer. You would do this assuming you have a Foo interface and a FooImpl class. Let us say you have:

Foo foo = new FooImpl();
// obtain an executor service from the java concurrent API.
// I wanted to give control to the caller to create this one so you can reuse thread pools.
ExecutorService executorService = Executors.newFixedThreadPool(10);
Foo asynchFoo = AsynchExecutor.getInstance(Foo.class, foo, executorService);
// Now invoke asynchFoo as if it is FooImpl.
asynchFoo.doSomething(); // where doSomething() exists in the Foo interface.
// this method should be void return type. Else we would return null.
// This is because the call would return immediately and the actual doSomething() task
// is queued up to be executed offline depending on the executorService passed to the
//getInstance() method above.

"

Stefan, 2012-09-18 08:53:21

Hi Raja, thanks for the explanation. It work very well now. Great piece of code ! The only thing we have changed is that we have put in the AsyncExecutor class following: private static ExecutorService executorService = Executors.newCachedThreadPool(); So we can proxy multiples classes without the need to create multiple newFixedThreadPool. So we have 1 Pool in the AsyncExecutor class that will handle all executions. This simplifies the use of hte AsyncExecutor class in the calling classes. Thx a lot again for sharing this... Regards, Stefan

Raja, 2012-09-19 18:35:34

Thanks Stefan. I understand the value of putting the executor service inside AsynchExecutor. The only reason I left it outside of it is so that you can re-use the thread pool whether you use the AsynchExecutor or not. i.e you can submit jobs to it ourside of the AsynchExecutor and do not have to deal with multiple executor services in your code - one created by the AsynchExecutor and the other outside.: I typically handle the construction of the ExecutorService and also the construction of the Asynch Executor in a framework like Spring so that you would never see the code I wrote above. Instead you would build the whole lot using static constructor invocations in Spring.