我正在尝试使两个嵌套循环并发。
假设我们有以下代码:
public MyClass
{
public void doSomething()
{
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < 1000; i++)
{
executor.execute(new InnerLoop(i, executor));
}
...
}
}
和
public InnerLoop extends Thread
{
...
public InnerLoop(int i, ExecutorService Executor)
{
...
}
public void run()
{
for (int j = 0; j < 1000; j++)
{
executor.execute(new InnerLoop2(i, j));
}
...
}
}
有什么办法可以让这个性能提高吗?在我看来,第二个 executor.execute(..) 调用会减慢速度,因为线程池已经忙于管理第一个循环中的线程。
最佳答案
Executor
委托(delegate)给其他线程的实现在 submit
或 execute
传递作业后立即返回到一个新线程或将作业排队。
这意味着您不需要考虑执行器“在第一个循环中管理线程”。 MyClass.doSomething()
内和 InnerLoop.run()
内的两个循环都可以非常快地处理,因为它们不做太多工作。将仅提交新作业并返回。
您需要担心的主要事情是,您可能有多达一百万个待处理的 InnerLoop2
作业,具体取决于您无法控制的处理顺序。使用 Executors.newCachedThreadPool()
返回的执行程序(在没有空闲线程时为每个作业创建一个新线程),这意味着您可能拥有最多一百万个线程。
拥有一百万个线程是否是一个问题很大程度上取决于系统和实现。一般来说,有些系统在处理大量线程时没有问题,它们只是将 cpu 时间分配给所有线程,其他系统可能会降低效率,甚至无法用于大量线程,但一百万是否已经是“高” number”可能再次取决于系统和硬件。
因此,如果有疑问,通常最好使用具有最大线程数的执行程序(您可以使用 Executors.newFixedThreadPool
或 new ThreadPoolExecutor
)并且,对于您的任务类型,将其与无界队列结合起来。
关于java - 带有线程池的嵌套循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26897819/