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