valerio
valerio

Reputation: 53

Java Spring bean that create more instances of another bean

I have this situation:

@RestController
@RequestMapping("/api")
public class A {

    @Autowired
    private B b;

    @RequestMapping(value = "/exec", method = RequestMethod.GET)
    public void execute(){
        int i = 0;
        for (i; i < 10; i++;){
            b.execute(i);
        }
    }

    @RequestMapping(value = "/exec/{i}", method = RequestMethod.GET)
    public void executeSingle(@PathVariable int i) {
        b.execute(i);
    }
}

@Service
public class B{
    public void execute(int i){
        //...a long time...
    }
}

Now I call method execute() of A and it takes long time because it call B.execute() consecutively.

I would like to have a parallel approach.

I would create multiple instances of bean B and call them at the same time, so I can gain about 9/10 of the time I spent with the actual "loop solution".

How can I do that?

Now to get these improvements I call 10 times method executeSingle(int i) of A, via browser with multiple HTTP GET like:

GET ADDRESS/api/exec/1

GET ADDRESS/api/exec/2

GET ADDRESS/api/exec/3

...

But I would like to use a more elegant solution.

Upvotes: 0

Views: 77

Answers (1)

Michael Gantman
Michael Gantman

Reputation: 7808

I would say that you need to use ExecutorService and in particular ThreadPoolExecutor Read about them to see how to use it. Then I would do the following changes to your code: change your B class to implement Runnable.

    public class B implements Runnable {
      private int myParam;

      public void setMyParam(int i) {
        myParam = i;
      }

    public void run() {
      execute(myParam)
    }

    private void execute(int i) {
      ...
    }
  }

Now don't make it a bean and don't inject it into your A class. But make a BclassFactory class that creates and returns a B class (or just create a new B class every time you need it. Now inject into your A class an instance of ThreadPoolExecutor and in your execute method do something like this:

   @RequestMapping(value = "/exec", method = RequestMethod.GET)
public void execute(){
    int i = 0;
    for (i; i < 10; i++;){
        B b = factory.getB();
        b.setMyParameter(i);
        executor.submit(b);
    }
}

That should do the trick

Upvotes: 1

Related Questions