1

In my web application that uses JSF, I have 100 records that is selected from the front end(using check box) and on clicking of a button , those selected 100 records needs to be initiated(it will create survey using RESTAPI call), which calls a method in bean that will make REST API call.

At present each record processed in a sequence and each record takes 20 sec on a average. so if I choose nearly 100 records I am getting request time out.. I am planning to call the method in bean using thread.. can you please tell how can I do? Method in the bean is initiatereview that takes reference number as parameter.

Namphibian
  • 12,046
  • 7
  • 46
  • 76
EnthuDev
  • 170
  • 2
  • 3
  • 15

1 Answers1

4

A managed bean is, in the end, a POJO. So, your problem boils down to how to use multiple threads to execute a similar task over different objects, so in the end is a Java problem rather than a JSF problem. For this, you have to use the ExecutorService interface. A brief example to accomplish this:

@ManagedBean
@RequestScoped
public class SomeBean {
    List<String> records;
    //other fields, constructor, getters and setters...
    public void foo() {
        int poolSize = records.size();
        ExecutorService executor = Executors.newFixedThreadPool(poolSize);
        for (final String record : records) {
            executor.execute(new Runnable() {
                public void run() {
                    //tasks to perform in the threads...
                }
            });
        }
        executor.shutdown();
    }
}

Some notes to this example:

  • poolSize value should not be records.size(), I just used this as example about creating a thread per work to perform. Note that you should create as many threads your server support. The real value of this variable will depend on result of your tests. I would recommend using 10 as initial value and then change it to measure the performance results.
  • You may create a class that implements Runnable interface that will hold the task you want to accomplish instead of creating an anonymous class.

Note that this is a possible solution. IMO it would be better sending the list of records to a component that will process them, for example via JMS call. Then the component will call your restful service and other things it must do to process the record.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • can you provide me an example for JMS? on click of commndbutton I am calling initiatereview method in a bean that has other methods also. initiatereview method takes an obj that is chosen as parameter. initiatereview method in turn calls another method in a class that makes RESTAPI call and email is sent. I need to do this in a thread. how can I pass parameter to a method in run.. can I use a class that implements runnable and in constructor pass the parameters.. – EnthuDev Oct 27 '13 at 12:02
  • @hemsush check here: https://blogs.oracle.com/soaproactive/entry/jms_step_2_using_the – Luiggi Mendoza Oct 27 '13 at 17:36
  • Also see how to properly shutdown: http://stackoverflow.com/questions/10504172/how-to-shutdown-an-executor-service – Christophe Roussy Jan 21 '14 at 10:32
  • @ChristopheRoussy you can use `shutdown` or `shutdownNow` to shutdown the executor, they are just two different ways to do it, the problem is when you do not shut it down causing leaks in your application. – Luiggi Mendoza Jan 21 '14 at 14:04
  • @LuiggiMendoza I did not mean that your solution is not the proper one, it was to show other existing solutions. – Christophe Roussy Jan 21 '14 at 16:16