我有一个800个Customer对象的列表,循环中的每个Customer对象都需要从数据库中获取一些额外的数据,但是这个单线程操作需要花费很多时间。
我的方法是将初始列表拆分为多个4列表,并相互并行执行每个列表。任何人都可以为我的问题陈述提出演示代码框架。
我很困惑我是否应该在实现Runnable接口的类的run()方法中编写我的数据库查询和业务逻辑,还是有更好的方法?
答案 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;
}
}