为什么在单线程,双线程和三线程程序中运行ExecutorService需要同时进行?

时间:2017-10-14 19:09:54

标签: java multithreading parallel-processing executorservice

我在非常低的温度下运行模拟薄膜。我尝试使用ExecutorService正确地多线程我的代码,并希望减少运行时。但我发现这说起来容易做起来难。我摆弄了许多参数,但无法提高效率。我发现奇怪的是,使用单线程,双线程或三线程ExecutorService运行代码的时间几乎相同。

底线是尽管for循环的更多迭代同时并行运行,但运行单次迭代所花费的时间量也会增加。无论使用多少处理器,总运行时间几乎相同。

我很困惑。我做错了什么?

public abstract class IsingRun {
public static void main(String[] args)  {   
    long starta = System.currentTimeMillis(); //time for single thread
    for (double t=temp[1];t<=temp[0] ;t+=temp[2] ) {
        long start = System.currentTimeMillis();
        //do stuff
        start = System.currentTimeMillis()-start;
        print(t,output,start); //start is the time taken for single iteration
    }
    starta = System.currentTimeMillis()-starta;
    System.out.println("Total Runtime (Single): "+ starta); //single thread total time

/*end of single threaded process */

    long startb = System.currentTimeMillis();
    ExecutorService e = Executors.newFixedThreadPool(2);
    for (double t=temp[1];t<=temp[0] ;t+=temp[2] ) {
        simulate s = new simulate(t);
        e.execute(s);

    }
    e.shutdown();
    startb = System.currentTimeMillis()-startb;
    System.out.println("Total Runtime (Double): "+ startb);

    /*end of double threaded process */

    long startc = System.currentTimeMillis();
    e = Executors.newFixedThreadPool(3);
    for (double t=temp[1];t<=temp[0] ;t+=temp[2] ) {
        simulate s = new simulate(t);
        e.execute(s);

    }
    e.shutdown();
    startc = System.currentTimeMillis()-startc;
    System.out.println("Total Runtime (Triple): "+ startc);
     /*end of triple threaded process */

}
}
class simulate implements Runnable{
simulate(double T){this.t=T;};

public void run() {
 long start = System.currentTimeMillis();
   //do stuff     
 start = System.currentTimeMillis()-start;
 print(t,output,start); //start is the time taken for single iteration
}
}

我得到了以下结果

Temp - Output - Runtime for single iteration
2.10 - 0.85410 - 632288
2.20 - 0.83974 - 646527
2.30 - 0.81956 - 655128
2.40 - 0.80318 - 645012
2.50 - 0.79169 - 649863
2.60 - 0.77140 - 662429
Total Runtime (Single): 3891257
2.10 - 0.85585 - 1291943
2.20 - 0.83733 - 1299240
2.40 - 0.80284 - 1313495
2.30 - 0.82294 - 1334043
2.50 - 0.79098 - 1315072
2.60 - 0.77341 - 1338203
Total Runtime (Double): 3964290
2.10 - 0.85001 - 1954315
2.20 - 0.84137 - 1971372
2.30 - 0.82196 - 1996214
2.40 - 0.80684 - 1966009
2.50 - 0.78995 - 1970542
2.60 - 0.77437 - 1966503
Total Runtime (Triple): 3962763

我做错了什么?任务管理器显示正在使用所有处理器,但是呢?

1 个答案:

答案 0 :(得分:1)

有几件事:

1)如果查看ExecutorService Javadoc,shutdown()方法不会等待线程完成执行。在您的代码中,您不是在等待任务实际完成。 javadoc还包含一些示例代码,演示如何正确等待ExecutorService完成。

2)基准测试计划并不是一件简单的事情。我可能/可能不信任这里的数字。另请参阅此SO post有关使用Java测量执行时间的信息。另外,我会分别测试你不同类型的执行方法,而不是一次性测试。

3)如果你的任务真的是CPU密集型的。我将创建一个ExecutorService,其线程数与您机器中的核心/处理器数量相匹配。如果你的任务是短暂的,那么线程/上下文切换的额外开销可能不值得,单线程可能是要走的路。