2

次のサンプルコードがあります。

import java.util.*;
import java.lang.*;
import java.io.*;

import java.util.concurrent.*;
public class CalculationThread implements Callable<Long> {

    public Long call() throws Exception {
        long k=0L;
        for(int i=0;i<100000;i++){
            for(int j=0;j<50;j++){
                k=i+j;
            }
        }
        return k;
    }
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        long startTime = System.nanoTime();
        for(int lo=0;lo<5000;lo++){
            Future<Long> result = executorService.submit(new CalculationThread());

            try {
                Long l = result.get();
            } catch (Exception e) {
                result.cancel(true);
            }

        }
        long endTime = System.nanoTime();
        System.out.println("Using threads took "+(endTime - startTime) + " ns");

        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.SECONDS);

        long k=0L;
        startTime = System.nanoTime();
        for(int lo=0;lo<5000;lo++){
            for(int i=0;i<100000;i++){
                for(int j=0;j<50;j++){
                    k=i+j;
                }
            }

        }
        endTime = System.nanoTime();
        System.out.println("Generally it takes "+(endTime - startTime) + " ns");

    }
}

出力は次のように広がります

Using threads took 101960490 ns
Generally it takes 143107865 ns

Using threads took 245339720 ns
Generally it takes 149699885 ns

お気づきのように、2 番目の行はほぼ一定ですが、スレッド化されたバージョンは大きく異なります。なぜそのような場合があるのですか?変動性を減らすために何ができるでしょうか?私はJavaマルチスレッドに慣れていないので、何か愚かなことをしている場合はお知らせください。

4

1 に答える 1

1

Future#get は、callable が終了するまでブロックします。そのため、メイン スレッドは Callable をプールに送信し、それが終了するのを待ってから次のスレッドを送信します。プールの 4 つのスレッドを作成するオーバーヘッドがあり、呼び出し可能オブジェクトを作成するスレッドとオブジェクト作成の間でコンテキスト スイッチがあり (呼び出し可能オブジェクトが破棄されるときにガベージ コレクションが実行されます)、次のいずれも実行していません。同時に作業。

プールを使用したバージョンの方が高速な数値を取得する方法は不可解です。これをローカルで実行すると (そして MVCE を作成するのがうまくいきました。ところで、変更なしでコピー アンド ペーストでき、動作します)、スレッドプール部分の数値が一貫して高くなり、シングルの約 3 倍の時間がかかります。スレッドコード。

于 2015-08-05T19:27:33.607 に答える