Executorservice的行为需要说明

问题描述 投票:0回答:1

请考虑以下伪代码

private ExecutorService mPool;

private final static int THREADS = Runtime.getRuntime().availableProcessors(); // which is 8 in my case

mPool = Executors.newFixedThreadPool(THREADS);

while ( go through a long list of images )
{
     if( !mPool.isShutdown() )
     {
         mPool.execute( new MyRunnable( path of image );
     }
}

....

....


private class MyRunnable implements Runnable
{
    public void run()
    {
         // do something with each image
    }
}

我已经用不同数量的线程执行了上述操作。以下是我的观察结果

100 threads  => 573 seconds
100 threads  => 584 seconds ( Just tried for a second time with same number of threads )
50 threads   => 574 seconds
10 threads   => 502 seconds
5 threads    => 589 seconds
1 thread     => 695 seconds 
8 threads    => 584 seconds ( Same number of threads as the number of cores in my phone )
4 threads    => 579 seconds
16 threads   => 581 seconds

我有以下问题。

1)为什么不使用4个线程不会增加两倍于我使用8个线程的时间?我观察到完成工作的时间几乎是相同的。

2)当我使用8个以上的线程时,操作系统是否仅考虑8个或更少的线程?

3)是否有更好的编程方法来解决此问题?

java android multithreading executorservice
1个回答
0
投票

在您的代码中,ExecutorService通过将Runnable分配给线程池中的特定线程来执行Runnable。

一旦线程完成执行,线程池可以为其重新分配一个新任务。换句话说,一个任务在一个线程中运行需要花费1个小时,而在2个线程中运行可能要花费40分钟。当我增加线程数时,代码花费的时间可能会减少,但是,即使有更多线程,也有可能在一天结束时仍未使用池中的许多线程。

因此,没有必要使用包含8个线程线程池的执行程序服务运行某些任务,执行时间将是4个线程的一半。这取决于分配的任务。

  • 我建议您检查此任务为每个单个图像运行一次所花费的时间。(我看到您有695秒内正在运行的1个线程的集合数据。)

  • 检查可运行代码。是否有任何同步块?这也会影响执行速度。

  • 总而言之,您需要分解代码并弄清楚哪些行在执行中花费时间。然后,您可以更好地将代码设计为彼此并行运行。

如果您共享更多代码,了解正在执行的操作以及如何精确计算执行时间,则可能会得到

© www.soinside.com 2019 - 2024. All rights reserved.