1. 概要
このチュートリアルでは、Javaスレッドにパラメーターを渡すために使用できるさまざまなオプションを実行します。
2. スレッドの基礎
簡単に言うと、Javaでスレッド を作成するには、 Runnable またはCallableを実装します。
スレッドを実行するには、を呼び出すことができます Thread#start (のインスタンスを渡すことによって実行可能 ) またスレッドプールを使用するに提出することによって ExecutorService。
ただし、これらのアプローチはどちらも追加のパラメーターを受け入れません。
パラメータをスレッドに渡すために何ができるか見てみましょう。
3. コンストラクターでパラメーターを送信する
スレッドにパラメーターを送信する最初の方法は、コンストラクターのRunnableまたはCallableにパラメーターを提供することです。
数値の配列を受け入れ、それらの平均を返すAverageCalculatorを作成しましょう。
public class AverageCalculator implements Callable<Double> {
int[] numbers;
public AverageCalculator(int... numbers) {
this.numbers = numbers == null ? new int[0] : numbers;
}
@Override
public Double call() throws Exception {
return IntStream.of(numbers).average().orElse(0d);
}
}
次に、平均的な計算機スレッドにいくつかの数値を提供し、出力を検証します。
@Test
public void whenSendingParameterToCallable_thenSuccessful() throws Exception {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Double> result = executorService.submit(new AverageCalculator(1, 2, 3));
try {
assertEquals(2.0, result.get().doubleValue());
} finally {
executorService.shutdown();
}
}
これが機能する理由は、スレッドを起動する前にクラスにその状態を渡したためです。
4. クロージャーを介したパラメーターの送信
パラメータをスレッドに渡す別の方法は、クロージャを作成する。です。
クロージャは、その親のスコープの一部を継承できるスコープです–ラムダと匿名の内部クラスで表示されます。
前の例を拡張して、2つのスレッドを作成しましょう。
最初のものは平均を計算します:
executorService.submit(() -> IntStream.of(numbers).average().orElse(0d));
そして、2番目は合計を行います:
executorService.submit(() -> IntStream.of(numbers).sum());
同じパラメーターを両方のスレッドに渡して結果を取得する方法を見てみましょう。
@Test
public void whenParametersToThreadWithLamda_thenParametersPassedCorrectly()
throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(2);
int[] numbers = new int[] { 4, 5, 6 };
try {
Future<Integer> sumResult =
executorService.submit(() -> IntStream.of(numbers).sum());
Future<Double> averageResult =
executorService.submit(() -> IntStream.of(numbers).average().orElse(0d));
assertEquals(Integer.valueOf(15), sumResult.get());
assertEquals(Double.valueOf(5.0), averageResult.get());
} finally {
executorService.shutdown();
}
}
覚えておくべき重要なことの1つは、パラメーターを効果的にファイナルに保つことです。そうしないと、パラメーターをクロージャーに渡すことができなくなります。
また、ここではどこでも同じ同時実行ルールが適用されます。スレッドの実行中に numbers 配列の値を変更した場合、なしで値が表示される保証はありません。 ]紹介いくつかの同期。
最後に、匿名の内部クラスも機能します。たとえば、古いバージョンのJavaを使用している場合は次のようになります。
final int[] numbers = { 1, 2, 3 };
Thread parameterizedThread = new Thread(new Callable<Double>() {
@Override
public Double call() {
return calculateTheAverage(numbers);
}
});
parameterizedThread.start();
5. 結論
この記事では、Javaスレッドにパラメーターを渡すために使用できるさまざまなオプションを発見しました。
いつものように、コードサンプルはGithubでから入手できます。