Рубрики
Без рубрики

Передача параметров java-потокам

Узнайте несколько способов отправки параметра в поток на Java

Автор оригинала: baeldung.

Передача параметров java-потокам

1. Обзор

В этом учебнике мы пройдемся по различным опциям, доступным для передачи параметров в поток Java.

2. Основы резьбы

В качестве краткого напоминания мы можем создать поток на Java по реализация Runnable или Вызов .

Чтобы запустить поток, мы можем вызвать Нить для начала (проходя экземпляр Бег ) или использовать пул потоков представив его на ИсполнительСервис .

Однако ни один из этих подходов не принимает никаких дополнительных параметров.

Давайте посмотрим, что мы можем сделать, чтобы передать параметры в поток.

3. Параметры отправки в конструкторе

Первый способ отправить параметр в поток просто предоставить его нашим Бег или Вызов в их конструктора.

Давайте создадим СреднийCalculator который принимает массив чисел и возвращает их в среднем:

public class AverageCalculator implements Callable {

    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 result = executorService.submit(new AverageCalculator(1, 2, 3));
    try {
        assertEquals(2.0, result.get().doubleValue());
    } finally {
        executorService.shutdown();
    }
}

Обратите внимание, что причина этого работает в том, что мы передали нашему классу его состояние перед запуском потока.

4. Отправка параметров через закрытие

Другим способом передачи параметров в поток является создание системы .

закрытие является областью, которая может унаследовать некоторые области его родителей – мы видим это с лямбдами и анонимными внутренними классами.

Давайте расширим наш предыдущий пример и создадим два потока.

Первый вычислит среднее значение:

executorService.submit(() -> IntStream.of(numbers).average().orElse(0d));

И, второй сделает сумму:

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 sumResult = 
          executorService.submit(() -> IntStream.of(numbers).sum()); 
        Future 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();
    }
}

Одна важная вещь, чтобы помнить, чтобы сохранить параметры эффективно окончательным или мы не сможем передать их закрытия.

Кроме того, здесь действуют те же правила конваляции, что и везде. Если мы изменим значение в цифры массив в то время как потоки работают, нет никакой гарантии, что они будут видеть его без введение некоторые синхронизированные .

И, чтобы завершить здесь, анонимный внутренний класс тоже работал бы, скажем, если бы мы использовали старую версию Java:

final int[] numbers = { 1, 2, 3 };
Thread parameterizedThread = new Thread(new Callable() {
    @Override
    public Double call() {
        return calculateTheAverage(numbers);
    }
});
parameterizedThread.start();

5. Заключение

В этой статье мы обнаружили различные варианты передачи параметров в поток Java.

Как всегда, образцы кода доступны более на Github .