Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Паралельний Stream API | Синхронізовані Колекції
Багатопотоковість у Java

bookПаралельний Stream API

Ви, ймовірно, вже знайомі з Stream API, його методами та принципом роботи (якщо ні, вивчіть цю тему, а потім поверніться до цього розділу).

Звичайний потік даних не є паралельним, тобто, яким би зручним і красивим не був код, використання Stream API без методу parallelStream() при великій кількості даних може суттєво вплинути на продуктивність.

Існує також метод parallel(), який можна використовувати після перетворення у stream.

List<Integer> result = list.stream().parallel()
                .map(num -> ++num)
                .toList();

Відмінність полягає в тому, що parallelStream() створює паралельний потік безпосередньо з колекції, тоді як parallel() перетворює вже існуючий послідовний потік у паралельний потік.

Note
Примітка

І найголовніше — нам, як програмістам, не потрібно нічого робити, окрім заміни методу stream() на parallelStream(). Stream API все виконує самостійно та оптимізує нашу програму!

Приклад: Обробка списку чисел

Припустимо, у нас є список чисел, і ми хочемо знайти суму квадратів усіх чисел у цьому списку.

Main.java

Main.java

copy
123456789101112131415161718192021222324252627
package com.example; import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of integers List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // Sequential stream to sum the squares of numbers int sumSequential = numbers.stream() // Create a sequential stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the sequential sum System.out.println("Sum of squares (sequential): " + sumSequential); // Parallel stream to sum the squares of numbers int sumParallel = numbers.parallelStream() // Create a parallel stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the parallel sum System.out.println("Sum of squares (parallel): " + sumParallel); } }

Як видно, ми просто замінили stream() на parallelStream() І ЦЕ ВСЕ. У цьому прикладі це не дасть жодного виграшу, оскільки в однопотоковому середовищі масив із 10 символів буде виконано швидше. Оскільки в реалізації Stream API виконується багато дій для розподілу завдання між потоками.

Note
Примітка

Stream API також самостійно визначає, скільки потоків буде використовувати для цього завдання, щоб забезпечити максимальну ефективність.

Як це працює під капотом:

1. Створення паралельного потоку: Коли ви викликаєте parallelStream(), Java створює паралельний потік на основі початкового джерела даних;

2. Використання ForkJoinPool (розглянемо пізніше): Паралельні потоки використовують спільний пул потоків, ForkJoinPool.commonPool(), який керує групою робочих потоків;

3. Розбиття: Дані у паралельному потоці діляться на частини за допомогою інтерфейсу Spliterator;

4. Обробка: Кожен робочий потік у ForkJoinPool обробляє свою частину даних;

5. Об'єднання: Після обробки даних робочі потоки об'єднують результати.

Переваги паралельних потоків

Підвищення продуктивності є однією з ключових переваг паралельних потоків, оскільки вони дозволяють розподіляти завдання між кількома потоками, що забезпечує швидшу обробку на багатоядерних процесорах.

Крім того, простота використання API паралельних потоків дозволяє легко інтегрувати їх у існуючий код, усуваючи необхідність у складному керуванні потоками.

Також значною перевагою є масштабованість, оскільки паралельні потоки автоматично підлаштовуються під кількість доступних ядер процесора, оптимізуючи виконання завдань.

1. Який клас використовується паралельними потоками для керування потоками?

2. Який метод використовується для створення паралельного потоку?

3. Яку роль виконує інтерфейс Spliterator у контексті паралельних потоків?

question mark

Який клас використовується паралельними потоками для керування потоками?

Select the correct answer

question mark

Який метод використовується для створення паралельного потоку?

Select the correct answer

question mark

Яку роль виконує інтерфейс Spliterator у контексті паралельних потоків?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 2. Розділ 2

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

Suggested prompts:

Can you explain when it's best to use parallel streams versus regular streams?

What are some potential drawbacks or risks of using parallel streams?

Can you provide more examples of using parallel streams in Java?

Awesome!

Completion rate improved to 3.33

bookПаралельний Stream API

Свайпніть щоб показати меню

Ви, ймовірно, вже знайомі з Stream API, його методами та принципом роботи (якщо ні, вивчіть цю тему, а потім поверніться до цього розділу).

Звичайний потік даних не є паралельним, тобто, яким би зручним і красивим не був код, використання Stream API без методу parallelStream() при великій кількості даних може суттєво вплинути на продуктивність.

Існує також метод parallel(), який можна використовувати після перетворення у stream.

List<Integer> result = list.stream().parallel()
                .map(num -> ++num)
                .toList();

Відмінність полягає в тому, що parallelStream() створює паралельний потік безпосередньо з колекції, тоді як parallel() перетворює вже існуючий послідовний потік у паралельний потік.

Note
Примітка

І найголовніше — нам, як програмістам, не потрібно нічого робити, окрім заміни методу stream() на parallelStream(). Stream API все виконує самостійно та оптимізує нашу програму!

Приклад: Обробка списку чисел

Припустимо, у нас є список чисел, і ми хочемо знайти суму квадратів усіх чисел у цьому списку.

Main.java

Main.java

copy
123456789101112131415161718192021222324252627
package com.example; import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of integers List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // Sequential stream to sum the squares of numbers int sumSequential = numbers.stream() // Create a sequential stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the sequential sum System.out.println("Sum of squares (sequential): " + sumSequential); // Parallel stream to sum the squares of numbers int sumParallel = numbers.parallelStream() // Create a parallel stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the parallel sum System.out.println("Sum of squares (parallel): " + sumParallel); } }

Як видно, ми просто замінили stream() на parallelStream() І ЦЕ ВСЕ. У цьому прикладі це не дасть жодного виграшу, оскільки в однопотоковому середовищі масив із 10 символів буде виконано швидше. Оскільки в реалізації Stream API виконується багато дій для розподілу завдання між потоками.

Note
Примітка

Stream API також самостійно визначає, скільки потоків буде використовувати для цього завдання, щоб забезпечити максимальну ефективність.

Як це працює під капотом:

1. Створення паралельного потоку: Коли ви викликаєте parallelStream(), Java створює паралельний потік на основі початкового джерела даних;

2. Використання ForkJoinPool (розглянемо пізніше): Паралельні потоки використовують спільний пул потоків, ForkJoinPool.commonPool(), який керує групою робочих потоків;

3. Розбиття: Дані у паралельному потоці діляться на частини за допомогою інтерфейсу Spliterator;

4. Обробка: Кожен робочий потік у ForkJoinPool обробляє свою частину даних;

5. Об'єднання: Після обробки даних робочі потоки об'єднують результати.

Переваги паралельних потоків

Підвищення продуктивності є однією з ключових переваг паралельних потоків, оскільки вони дозволяють розподіляти завдання між кількома потоками, що забезпечує швидшу обробку на багатоядерних процесорах.

Крім того, простота використання API паралельних потоків дозволяє легко інтегрувати їх у існуючий код, усуваючи необхідність у складному керуванні потоками.

Також значною перевагою є масштабованість, оскільки паралельні потоки автоматично підлаштовуються під кількість доступних ядер процесора, оптимізуючи виконання завдань.

1. Який клас використовується паралельними потоками для керування потоками?

2. Який метод використовується для створення паралельного потоку?

3. Яку роль виконує інтерфейс Spliterator у контексті паралельних потоків?

question mark

Який клас використовується паралельними потоками для керування потоками?

Select the correct answer

question mark

Який метод використовується для створення паралельного потоку?

Select the correct answer

question mark

Яку роль виконує інтерфейс Spliterator у контексті паралельних потоків?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 2. Розділ 2
some-alt