Reputation: 53
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
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