Executorservice的行为需要说明

时间:2019-11-24 15:26:29

标签: java android multithreading executorservice

请考虑以下伪代码

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)是否有更好的编程方法来解决此问题?

1 个答案:

答案 0 :(得分:0)

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

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

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

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

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

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

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