请考虑以下伪代码
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)是否有更好的编程方法来解决此问题?
答案 0 :(得分:0)
在您的代码中,ExecutorService通过将Runnable分配给线程池中的特定线程来执行Runnable。
线程完成执行后,线程池可以为其重新分配一个新任务。 换句话说,一个任务在一个线程中运行需要花费1个小时,而在2个线程中运行可能要花费40分钟。当我增加线程数时,代码花费的时间可能会减少,但是即使有更多线程,也有可能在一天结束时池中的许多线程仍未使用。
因此,没有必要使用包含8个线程线程池的executor服务运行某些任务,执行时间将是4个线程的一半。 这取决于要分配的任务。
我建议您检查此任务为每个单个图像运行一次所花费的时间。 (我看到您有695秒内正在运行的1个线程的集合数据。)
检查可运行代码。是否有任何同步块?那也会影响执行速度。
总而言之,您需要分解代码并找出哪些行在执行中花费时间。然后,您可以更好地将代码设计为彼此并行运行。
如果您共享正在执行的操作以及如何精确计算执行时间的代码,则可能会获得