我有List<Object> objectsToProcess.
让我们说它包含1000000项目。对于数组中的所有项目,您可以像这样处理每个项目:
for(Object : objectsToProcess){
Go to database retrieve data.
process
save data
}
我的问题是:多线程会提高性能吗?我认为处理器默认会分配多线程吗?
答案 0 :(得分:7)
在所描述的场景中,假设该过程是一项耗时的任务,并且假设CPU具有多个核心,则多线程确实可以提高性能。
处理器不是分配线程的人。处理器是通过提供多个执行单元/执行上下文来提供线程可以使用的资源(虚拟CPU /虚拟处理器)的处理器。程序需要自己创建多个线程,以便同时使用多个CPU内核。
多线程的两个主要原因是:
有编程语言和执行环境,其中将自动创建线程以处理可并行化的问题。 Java还不是其中之一,但是从Java 8开始,它就是一个很好的方式,而Java 9可能会带来更多。
通常您不需要比CPU提供CPU内核多得多的线程,原因很简单,线程切换和线程同步是开销减慢的原因。
包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
是可以提供并行流的内容,您也可以这样做:
objectsToProcess.parallelStream().forEach(object -> {
Go to database retrieve data.
process
save data
});
这将决定如何处理VM的线程,这通常比自己实现多线程更好。
进一步阅读:
答案 1 :(得分:1)
取决于花费的时间。
如果要进行大量计算,那么将工作分配给更多线程会有所帮助,正如您所说,每个线程可以在单独的CPU上执行。在这种情况下,拥有比CPU更多的线程没有价值。正如Corbin所说,你必须弄清楚如何跨线程分割工作,并负责启动线程,等待完成并聚合结果。
如果您正在等待数据库,那么使用线程可能会有额外的价值。数据库可以在paraallel中提供多个请求(数据库服务器本身是多线程的),而不是编码
for(Object : objectsToProcess){
Go to database retrieve data.
process
save data
}
如果在发出下一个响应之前等待每个响应,则希望每个响应都有多个工作线程
Go to database retrieve data.
process
save data
然后你获得更好的吞吐量。但技巧是不要有太多的工作线程。有几个原因:
Net:你几乎可以肯定通过拥有一些工作线程来获益。帮助的线程数将由诸如您拥有的CPU数量以及您执行的处理量与来自DB的响应时间之间的因素确定。您只能通过实验确定,因此可以配置和调查线程数。从5开始,然后是10.随着线程数量的增加,密切注意数据库上的负载。