Основные принципы многопоточности

Оптимизация кода на Java

Pavlos Kosmetatos

Lead Engineer @Wealthyhood

Последовательное и параллельное выполнение

  • Последовательная обработка -> операции выполняются одна за другой
  • Параллельная обработка -> несколько операций выполняются одновременно

Как это работает?

  • Современные процессоры имеют несколько ядер
  • Поток: минимальная единица выполнения программы
  • Многопоточность распределяет работу между ядрами

Однопоточность — как однополосная дорога, где машины едут друг за другом. Многопоточность — как многополосная, где машины движутся одновременно!

Оптимизация кода на Java

Работа с потоками

  • Класс Thread позволяет создавать новые пути выполнения
  • Каждый Thread может выполняться независимо
Runnable task = () -> {
    System.out.println("Processing on thread: " + 
                       Thread.currentThread().getName());
};

Thread thread = new Thread(task);
thread.start();
Processing on thread: Thread-0
Оптимизация кода на Java

Работа с несколькими потоками

List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 4; i++) {
    Thread thread = new Thread(() -> System.out.println("Processing data on Thread-" + i));
    threads.add(thread);
    thread.start();
}

for (Thread t : threads) {
    t.join(); // Waits for all threads to complete
}
// Processing data on Thread-0
// Processing data on Thread-2
// Processing data on Thread-1
// Processing data on Thread-3
Оптимизация кода на Java

Параллельные потоки

  • Streams — возможность Java 8+ для упрощённого параллелизма
  • Автоматически управляет созданием потоков и их жизненным циклом
  • Два способа создания:
    • collection.parallelStream()
    • Stream.of(...).parallel()
Оптимизация кода на Java

Пример параллельных потоков

// Sequential processing
List<Integer> result1 = new ArrayList<>();
for (int i = 0; i < numbers.size(); i++) {
    result1.add(numbers.get(i) * 2);
}

// Sequential processing with stream List<Integer> result2 = numbers.stream() .map(n -> n * 2) .collect(Collectors.toList());
// Parallel processing with parallel stream List<Integer> result3 = numbers.parallelStream() .map(n -> n * 2) .collect(Collectors.toList());
Оптимизация кода на Java

Когда использовать параллельную обработку

  • Ресурсоёмкие вычислительные операции
  • Независимая обработка данных
  • Большие коллекции данных
  • Доступных ядер процессора > 1
  • Накладные расходы на параллелизацию могут не окупиться при:
    • Малых объёмах данных
    • Простых операциях
Оптимизация кода на Java

Итоги

  • Класс Thread — для создания параллельных путей выполнения
  • Параллельные потоки — для упрощённой обработки коллекций
  • Эффективность зависит от:
    • Типа нагрузки
    • Объёма данных
    • Доступных ядер
Оптимизация кода на Java

Давайте потренируемся!

Оптимизация кода на Java

Preparing Video For Download...