いくつかの演習がありますが、そのうちの 1 つは同時実行性に関するものです。このテーマは私にとって新しいものですが、6 時間かけてようやく問題を解決しました。しかし、対応する API の知識が乏しいので、アドバイスが必要です: 私の解決策は正しいですか、それとももっと適切な方法があるかもしれません。
したがって、次のインターフェイスを実装する必要があります。
public interface PerformanceTester {
/**
* Runs a performance test of the given task.
* @param task which task to do performance tests on
* @param executionCount how many times the task should be executed in total
* @param threadPoolSize how many threads to use
*/
public PerformanceTestResult runPerformanceTest(
Runnable task,
int executionCount,
int threadPoolSize) throws InterruptedException;
}
PerformanceTestResultには、合計時間 (パフォーマンス テスト全体の合計所要時間)、最小時間 (最短の 1 回の実行にかかった時間)、および最大時間 (最長の 1 回の実行にかかった時間) が含まれます。
そのため、今日、スレッド プール、タイプ、、、などについて多くの新しいことを学びましExecutors
た。ExecutorService
Future
CompletionService
があれば Callable task
、次に作ることができます:
call()
プロシージャの最後で現在の時刻を返します。Future
開始時刻とオブジェクトを格納するためのデータ構造fixedThreadPool.submit(task)
(いくつかの Map である可能性があります) を作成executionCount
します。- 実行後、すべての終了時間から開始時間を差し引くことができました
Future
。
( Callable タスクの場合はこれでいいのでしょうか?)
しかし!しかないRunnable task
ので、探し続けました。FutureListener implements Callable<Long>
私は、時間を返さなければならない を作成しますFuture.isDone()
.
そのため、最終的に、次の完了したタスクを表す Futureを取得して削除し、まだ存在しない場合は待機する、CompletionService
興味深いメソッドを持つ型に気付きました。、およびExecutorCompletionServiceを使用した非常に良い例です。そして、私の解決策があります。take()
public class PerformanceTesterImpl implements PerformanceTester {
@Override
public PerformanceTestResult runPerformanceTest(Runnable task,
int executionCount, int threadPoolSize) throws InterruptedException {
long totalTime = 0;
long[] times = new long[executionCount];
ExecutorService pool = Executors.newFixedThreadPool(threadPoolSize);
//create list of executionCount tasks
ArrayList<Runnable> solvers = new ArrayList<Runnable>();
for (int i = 0; i < executionCount; i++) {
solvers.add(task);
}
CompletionService<Long> ecs = new ExecutorCompletionService<Long>(pool);
//submit tasks and save time of execution start
for (Runnable s : solvers)
ecs.submit(s, System.currentTimeMillis());
//take Futures one by one in order of completing
for (int i = 0; i < executionCount; ++i) {
long r = 0;
try {
//this is saved time of execution start
r = ecs.take().get();
} catch (ExecutionException e) {
e.printStackTrace();
return null;
}
//put into array difference between current time and start time
times[i] = System.currentTimeMillis() - r;
//calculate sum in array
totalTime += times[i];
}
pool.shutdown();
//sort array to define min and max
Arrays.sort(times);
PerformanceTestResult performanceTestResult = new PerformanceTestResult(
totalTime, times[0], times[executionCount - 1]);
return performanceTestResult;
}
}
それで、あなたは何を言うことができますか?返信ありがとうございます。