Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带线程池的嵌套循环_Java_Multithreading_Concurrency_Threadpool_Executor - Fatal编程技术网

Java 带线程池的嵌套循环

Java 带线程池的嵌套循环,java,multithreading,concurrency,threadpool,executor,Java,Multithreading,Concurrency,Threadpool,Executor,我试图使两个嵌套循环并发 假设我们有以下代码: public MyClass { public void doSomething() { ExecutorService executor = Executors.newCachedThreadPool(); for (int i = 0; i < 1000; i++) { executor.execute(new InnerLoop(i, executor)); } ..

我试图使两个嵌套循环并发

假设我们有以下代码:

public MyClass 
{
  public void doSomething()
  {
    ExecutorService executor = Executors.newCachedThreadPool();

    for (int i = 0; i < 1000; i++)
    {
        executor.execute(new InnerLoop(i, executor));
    }

    ...
  }
}

有没有办法让这场演出更精彩?在我看来,第二个遗嘱执行人。。调用会减慢速度,因为线程池已经忙于管理第一个循环中的线程。

委托给其他线程的执行器实现在提交或执行后立即返回,将作业传递给新线程或将作业排队

这意味着您不需要考虑执行器“在第一个循环中管理线程”。MyClass.doSomething和InnerLoop.run中的两个循环都可以很快处理,因为它们不需要做很多工作。他们将提交新的工作并返回

您需要关注的主要问题是,根据您无法控制的处理顺序,您可能有多达一百万个待处理的InnerLoop2作业。如果Executors.newCachedThreadPool返回一个executor,当没有空闲线程时,它会为每个作业创建一个新线程,这意味着您可能有多达一百万个线程

拥有一百万个线程是否是一个问题在很大程度上取决于系统和实现。一般来说,有很多线程的系统都没有问题,它们只是将cpu时间分配给所有线程,其他系统的效率可能会降低,导致大量线程无法使用,但一百万是否已经是一个“高数字”可能再次取决于系统和硬件


因此,如果有疑问,通常最好使用具有最多线程数的执行器。newFixedThreadPool或new ThreadPool executor,对于您的任务,将其与无限队列结合起来。

许多人不喜欢冗长的教程,@Holger回答了眼前的问题,真正的问题似乎是缺乏对一般原则的理解

最佳并发性好处来自于高效地使用所有可用资源。这通常意味着适应内核的数量,即不使用比内核更多的活动线程,使线程真正相互独立,以及其他许多事情。这可以通过使用线程池来实现,但是应该了解线程池的功能


彻底的回答意味着重复大部分内容,因此一个好的开始是——一如既往地——我刚才所说的不是真的。除非有线程可用,否则newCachedThreadPool将为每个新任务创建一个新线程。InnerLooprun是否执行任何实际工作,或者它是否仅用于生成和调度InnerLoop2?我将首先用可运行的工具替换extends Thread。您可能希望使用像ForkJoinPool这样的工具,它将尽可能多地将内容保持在同一个线程中。@Misha不,它不做任何实际工作。
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));
    }

    ...
  }  
}