Wednesday, January 27, 2010

Asynchronous Groovy

In my previous post, i showed how simple asynchronous code in Spring 3 is. I wanted to see what it takes to write the same code in Groovy. Well, it is quite straightforward, using the GPARS library. The docs there show it to be quite powerful, but to be loyal to our simple example, here is the code:



   1: Asynchronizer.withAsynchronizer(4) {ExecutorService service ->



   2:       (0..9).each { num->



   3:         service.submit({



   4:         Thread.sleep(2000);



   5:         println("Running for ${num} thread ${Thread.currentThread()}")}as Runnable)



   6:       }



   7: }



See how you specify the number of threads in the parameter to the closure withAsynchronizer.
There are lots more examples at the GPARS site.

Wednesday, January 13, 2010

Asynchronous Code with Spring 3 – Simple as an annotation

After reviewing some of the features of Spring 3, i decided to test out the asychronous features via annotation. And below is all the code i needed in order to have a function executed asynchronously in my application:



   1: public class Asyncher {



   2:     @Async



   3:     public void myMethod(int i) {



   4:         try {



   5:             Thread.sleep(2000);



   6:         } catch (InterruptedException e) {



   7:             e.printStackTrace();



   8:         }



   9:         System.out.println("Running for " + i);



  10:     }



  11:  



  12:     public static void main(String[] args) throws InterruptedException {



  13:         ApplicationContext ctx = new ClassPathXmlApplicationContext("appContext.xml");



  14:         Asyncher a = ctx.getBean("asyncher", Asyncher.class);



  15:         for (int i=0; i<10;i++) {



  16:                 a.myMethod(i);



  17:         }      



  18:  



  19:         ThreadPoolTaskExecutor t = ctx.getBean("myExecutor",ThreadPoolTaskExecutor.class);



  20:         while (t.getActiveCount() > 0) {



  21:             System.out.println("Number of tasks left: " + t.getActiveCount());



  22:             Thread.sleep(2000);



  23:         }



  24:         t.shutdown();



  25:     }



  26: }



Hard to believe, but all i needed to do was add the Async annotation on line 2 to my function and it works. of course we need a few lines in our application Context to make this work, but here they are:


   1: <?xml version="1.0" encoding="UTF-8"?>



   2: <beans xmlns="http://www.springframework.org/schema/beans"



   3:        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"



   4:        xmlns:context="http://www.springframework.org/schema/context"



   5:        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">



   6:  



   7:     <task:annotation-driven executor="myExecutor" />



   8:     <task:executor id="myExecutor" pool-size="2"/>



   9:     <bean id="asyncher" class="Asyncher"/>



  10:  



  11: </beans>


This same method can be used to create scheduled jobs as well, by changing or adding on line 7 the scheduler attribute and then adding in a scheduler bean

<task:scheduler id="myScheduler" pool-size="10"/>

You can read about it in the docs here