我是Multithreading
的新手,我正在尝试使用ExecutorService
让我的程序更快。下面是y实现,但是,我的程序仍然没有快速工作。你能看一下我的代码并提出建议吗?
它基本上会在ArrayList
中读取电子邮件地址和商店列表。我使用ExecutorService
并遍历ArrayList
并调用Callable类进行一些处理并返回一个布尔值。
ArrayList<String> emailAddressList = new ArrayList<>();
ExecutorService executor = Executors.newFixedThreadPool(7);
for (int i = 0; i < emailAddressList.size(); i++) {
Future<Boolean> resultFromThread = executor.submit(new Verify(emailAddressList.get(i)));
bufferedWriter.write(emailAddressList.get(i) + "|" + resultFromThread.get());
bufferedWriter.newLine();
}
executor.shutdown();
executor.awaitTermination(3, TimeUnit.SECONDS);
=============================================== ============================
public class Verify implements Callable<Boolean> {
private String email;
public Verify(String email) {
this.email = email;
}
@Override
public Boolean call() throws Exception {
Boolean result = false;
try {
result = Validator2.isAddressValid(email);
} catch (Exception e) {
}
return result;
}
}
答案 0 :(得分:2)
在循环的每次迭代中,执行两个动作:
这样,所有Callables仍然以串行方式执行(我们等待在提交另一个之前完成一个),而不是并行执行它们。
一个简单的解决方案可能是首先提交所有可执行的callables。然后,在一个单独的循环中,等待它们完成并处理结果。这样,由于Callables的并行处理,性能将得到改善。
示例:
List<Future<Boolean>> futures ... ;
for (int i = 0; i < emailAddressList.size(); i++) {
futures.add(executor.submit(new Verify(emailAddressList.get(i))));
}
for (int i = 0; i < emailAddressList.size(); i++)
bufferedWriter.write(emailAddressList.get(i) + "|" + futures.get(i).get());
bufferedWriter.newLine();
}
请注意,此代码等待Callables按照提交给Executor的顺序完成。这可能不一定是这种情况。如果结果写入器中的地址顺序不重要,则可以考虑完全异步处理。在Java 8中,这可以使用CompleteableFuture API来实现。
答案 1 :(得分:0)
您已经有效地使代码同步和单线程,而没有使用线程执行程序的任何优势。当调用resultFromThread.get()时,它将阻塞主线程并阻止下一个循环迭代,该循环迭代提交下一个要执行的任务,直到前一个完成。如果您希望提交的验证任务同时运行,则应首先在附加到List<Future<Boolean>>
的一个循环中提交所有任务。然后,在另一个循环中,您可以遍历每个循环,然后调用.get(),这样主线程将等待所有执行完成,但不会阻止其他7个线程同时执行。