-1

I have a list of 800 Customer objects and each Customer object in loop needs to fetch some additional data from the database, but this single thread operation is taking a lot of time.

My approach is to split the initial list in to multiple lists of 4 and to execute each list in parallel to each other. Can any one come up with a demo code skeleton for my problem statement.

I am confused whether I should write my db queries and business logic inside run() method of Class implementing Runnable interface or any better approach is there?

Mike Laren
  • 8,028
  • 17
  • 51
  • 70
Rohan K
  • 177
  • 1
  • 3
  • 21

2 Answers2

0

800 is not a large number of rows to bring back. What's killing you is your loop, where you're performing a separate query for each of these rows. This is called the n + 1 selects antipattern.

Using multiple threads will not improve anything, network round trips were the problem before and adding threads doesn't do anything to make that better. Instead write one query that will join from the customer to whatever it needs, bringing back all the data in one resultset. This minimizes the number of trips across the network to get your data.

Community
  • 1
  • 1
Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • Nathan its not opnly db queries thats adding complexity , there are some if else business logic also. So what I thought instead one customer being processed at one time, if there are 4 threads it can execute business logic+ db queries for 4 customers in parallel.... Let me know if my approach is missing something... – Rohan K Jun 19 '15 at 03:39
  • 1
    get all data from DB as one shot first, and do your "business logic" in parallel maybe. However it is rare the bottleneck is the "business logic" involve no network/db round trip – Adrian Shum Jun 19 '15 at 04:06
0
public static void main(String[] args) throws InterruptedException, ExecutionException {
    final int objectsCount = 800;
    final int threads = 4;
    final int objectsPerThread = objectsCount / threads;

    List<Object> yourObjects = new ArrayList<>(800);//your 800 objects stored here

    final CompletionService<Void> completionService =
            new ExecutorCompletionService<>(
                    Executors.newFixedThreadPool(threads));

    for (int from = 0; from < objectsCount; from += objectsPerThread) {
        completionService.submit(new DoItInParallel(yourObjects.subList(from, from += 200)));
    }

    for (int i = 0; i < threads; i++) {
        completionService.take().get();
    }
}


public class DoItInParallel implements Callable<Void> {

private final List<Object> objects;

public DoItInParallel(List<Object> objects) {
    this.objects = objects;
}

@Override
public Void call() throws Exception {
    for (Object object : objects) {
        //here you can call your services or just use jdbc api to retrieve data from db and do some business logic
    }
    return null;
}

}

Rostyslav
  • 91
  • 2
  • 6