对象列表的多线程

时间:2015-06-19 03:20:25

标签: java spring

我有一个800个Customer对象的列表,循环中的每个Customer对象都需要从数据库中获取一些额外的数据,但是这个单线程操作需要花费很多时间。

我的方法是将初始列表拆分为多个4列表,并相互并行执行每个列表。任何人都可以为我的问题陈述提出演示代码框架。

我很困惑我是否应该在实现Runnable接口的类的run()方法中编写我的数据库查询和业务逻辑,还是有更好的方法?

2 个答案:

答案 0 :(得分:0)

800不会带回大量的行。什么杀了你就是你的循环,你在这里为每一行执行单独的查询。这称为n + 1 selects antipattern

使用多线程不会改善任何事情,网络往返是之前的问题,添加线程并没有做任何事情来改善它。而是编写一个将从客户加入到任何需要的查询,将一个结果集中的所有数据带回来。这样可以最大限度地减少网络中的数据,以获取数据。

答案 1 :(得分: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;
}

}