代码之家  ›  专栏  ›  技术社区  ›  CIOC

使用多条线时如何避免瓶颈?

  •  0
  • CIOC  · 技术社区  · 5 年前

    我有以下循环:

    // myList is an ArrayList (10000 elements)
    for(MyObject test : myList) {
        test.calculate();
    }
    

    calculate() 操作不依赖于其他任何东西,它只使用同一对象中的某些变量进行一些数学操作。

    我知道执行以下操作将对性能产生负面影响,因为我将创建10000个线程,这将在我的4核处理器上创建一个巨大的队列:

    // myList is an ArrayList (10000 elements)
    for(MyObject test : myList) {
        Thread thread = new Thread() {
            public void run() {
                test.calculate();
            }  
        };
        thread.start();
    }
    

    2 回复  |  直到 5 年前
        1
  •  2
  •   David Siegal    5 年前

    一种更简单的方法是利用Java 8并行流。

    myList.parallelStream().forEach( MyObject::calculate);
    

    JVM为这些任务维护一个线程池,其中的线程数量与计算机上的核心(或超线程)数量相同。它不会在每次遇到并行代码时启动一个新的池;也不会在每次迭代时启动一个新线程。

    当然,对于任何性能问题,都要做基准测试。在多个线程之间分叉工作,然后连接结果(可能需要捕获结果)会有一些开销。因此,要确保节省的费用超过管理费用。

        2
  •  4
  •   assylias    5 年前

    an ExecutorService -根据您的描述,您希望每个处理器使用一个线程:

    int nThreads = Runtime.getRuntime().availableProcessors();
    ExecutorService executor = Executors.newFixedThreadPool(nThreads);
    
    for (MyObject test: myList) {
      executor.submit(test::calculate);
    }
    
    executor.shutdown();