多线程可以提高性能吗?方案java

时间:2014-12-20 07:50:10

标签: java multithreading

我有List<Object> objectsToProcess.让我们说它包含1000000项目。对于数组中的所有项目,您可以像这样处理每个项目:

for(Object : objectsToProcess){
    Go to database retrieve data.
    process
    save data
}

我的问题是:多线程会提高性能吗?我认为处理器默认会分配多线程吗?

2 个答案:

答案 0 :(得分:7)

在所描述的场景中,假设该过程是一项耗时的任务,并且假设CPU具有多个核心,则多线程确实可以提高性能。

处理器不是分配线程的人。处理器是通过提供多个执行单元/执行上下文来提供线程可以使用的资源(虚拟CPU /虚拟处理器)的处理器。程序需要自己创建多个线程,以便同时使用多个CPU内核。

多线程的两个主要原因是:

  • 利用多个CPU核心,否则这些CPU核心将被使用或者至少无助于减少解决给定问题所需的时间 - 如果问题可以分为可以彼此独立处理的子问题(可以并行化) )。
  • 使程序同时对多个事物起作用(即Event Thread vs. Swing Worker)。

有编程语言和执行环境,其中将自动创建线程以处理可并行化的问题。 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

然后你获得更好的吞吐量。但技巧是不要有太多的工作线程。有几个原因:

  1. 每个线程都使用一些资源,它拥有自己的堆栈,它自己的堆栈 连接到数据库。你不会想要10,000个这样的线程。
  2. 每个请求都使用服务器上的资源,每个连接使用内存,每个数据库服务器只会并行处理这么多请求。如果它只能并行处理数十个请求,那么提交数千个并发请求就没有任何好处。此外,如果共享数据库,您可能不想满足您的请求使数据库饱和,您需要成为一个“好公民”#34;。
  3. Net:你几乎可以肯定通过拥有一些工作线程来获益。帮助的线程数将由诸如您拥有的CPU数量以及您执行的处理量与来自DB的响应时间之间的因素确定。您只能通过实验确定,因此可以配置和调查线程数。从5开始,然后是10.随着线程数量的增加,密切注意数据库上的负载。