我有一个 List<Object> objectsToProcess
,假设它包含1000000个元素。对于数组中的每个元素,您可以像这样处理:
for(Object : objectsToProcess){
Go to database retrieve data.
process
save data
}
我的问题是:多线程能提高性能吗?我认为处理器默认会分配多个线程,对吗?
我有一个 List<Object> objectsToProcess
,假设它包含1000000个元素。对于数组中的每个元素,您可以像这样处理:
for(Object : objectsToProcess){
Go to database retrieve data.
process
save data
}
我的问题是:多线程能提高性能吗?我认为处理器默认会分配多个线程,对吗?
java.util.concurrent
包提供了许多类,可帮助解决多线程的典型问题。您需要的是一个ExecutorService
,将要并行运行和完成的任务分配给它。类Executors
提供了用于创建流行类型的ExecutorService
的工厂方法。如果您的问题只需要在并行环境下解决,可以选择Executors.newCachedThreadPool()
。如果您的问题很紧急,则可以选择Executors.newWorkStealingPool()
。final ExecutorService service = Executors.newWorkStealingPool();
for (final Object object : objectsToProcess) {
service.submit(() -> {
Go to database retrieve data.
process
save data
}
});
}
objectsToProcess.parallelStream().forEach(object -> {
Go to database retrieve data.
process
save data
});
这取决于时间花费在哪里。
如果你有一堆计算需要执行,将工作分配到更多线程可以帮助,就像你说的每个线程可能在单独的CPU上执行。在这种情况下,拥有比CPU更多的线程是没有价值的。正如Corbin所说,你必须想出如何在线程之间划分工作,并负责启动线程,等待完成和聚合结果。
如果像你的情况一样,你正在等待一个数据库,那么使用线程可能会增加额外的价值。数据库可以并行地处理几个请求(数据库服务器本身是多线程的),因此不用编写
for(Object : objectsToProcess){
Go to database retrieve data.
process
save data
}
如果您需要等待每个响应后再发出下一个请求,那么您需要有多个工作线程同时执行。
Go to database retrieve data.
process
save data
这样可以获得更好的吞吐量。但是,关键在于不要有太多的工作线程。原因如下:
总之:通过拥有一定数量的工作线程,您几乎肯定会获得益处。哪些数量的线程有帮助将由因素(例如您拥有的 CPU 数量以及您执行的处理量与 DB 响应时间之间的比率)决定。你只能通过实验来真正确定这个数字,所以让线程数量可配置并进行调查。从 5 开始,然后是 10。随着增加线程数量,注意数据库的负载。