MSR
MSR

Reputation: 63

How to Use Executor Service and have multiple runnable in java 7

I am really having tough time implementing this. I recently learned multithreading and started using executor service to run job asynchronously.

I have a situation here like:

final ArrayList<String> sList = new ArrayList<String>();
final ArrayList<String> gList = new ArrayList<String>();
 final JSONArray stateId = [JSON ARRAY WITH JSON DATA]
//ExecutorService exec = new FixedThreadPoll(10);
for(String sId : stateId){
   for(String sItem : sList){
     for(String gItem: gList){
        //do an API call
      lisA.add(somthing);
     }
   }
}

And next i need to iterate the list and create one more list inside it.

for(String a : listA){
       for(String sItem : sList){
         for(String gItem: gList){
            //do an API call
          lisB.add(somthing);
         }
       }
    }

I want to make use of executor service here for the loops and reduce the execution time by running the loop asynchronously. But i am not able to do that.I have tried the following:

ExecutorService exec = new FixedThreadPoll(10);
for(String sId : stateId){
 executor.execute(new Runnable() {
 @Override
 public void run() {
   for(String sItem : sList){
     for(String gItem: gList){
        //do an API call
      lisA.add(somthing);
     }
   }
});
 }

I have to make some variable final which i cant do that as the value needs to be assigned every time in the loop or else i get the following error:" Cannot refer to the non-final local variable gList defined in an enclosing scope".

Can anyone help me out how to use Executor service in both the loops to compete this task please.have spent a lot of time. I understood the concept but having trouble implementing it.

Upvotes: 0

Views: 2282

Answers (1)

Andrew Rueckert
Andrew Rueckert

Reputation: 5225

The important thing to note is that every variable that you define outside of the Runnable that is used inside the Runnable must be final.

public static void main(String... args) throws Exception {
    final ExecutorService exec = Executors.newFixedThreadPool(10);
    final ArrayList<String> sList = new ArrayList<String>();
    final ArrayList<String> gList = new ArrayList<String>();
    final List<String> stateId = new ArrayList<>();
    final ArrayList<String> lisA = new ArrayList<>();

    for(final String sId : stateId) {
        exec.execute(new Runnable() {
            @Override
            public void run() {
                for (String sItem : sList) {
                    for (String gItem : gList) {
                        //do an API call
                        lisA.add(sId);
                    }
                }
            }
        });
    }
}

If you have a variable that cannot be final, but you still need to use it inside your runnable, you can declare a new final variable that is set equal to the non-final variable:

public static void main(String... args) throws Exception {
    final ExecutorService exec = Executors.newFixedThreadPool(10);
    final ArrayList<String> sList = new ArrayList<String>();
    final ArrayList<String> gList = new ArrayList<String>();
    final List<String> stateId = new ArrayList<>();
    final ArrayList<String> lisA = new ArrayList<>();

    // sId is non-final
    for(String sId : stateId) {
        // f_sId is final; it will be sId's current value
        final String f_sId = sId;
        exec.execute(new Runnable() {
            @Override
            public void run() {
                for (String sItem : sList) {
                    for (String gItem : gList) {
                        //do an API call
                        lisA.add(f_sId);
                    }
                }
            }
        });
    }
}

Upvotes: 1

Related Questions