Домой java Примеры параллельных потоков Java 8

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

670
0

Содержание

Несколько примеров Java 8 для параллельного выполнения потоков.

1. BaseStream.parallel ()

Простой параллельный пример для печати от 1 до 10.

ParallelExample1.java


package com.csharpcoderr.java8;

import java.util.stream.IntStream;

public class ParallelExample1 {

public static void main(String[] args) {

System.out.println("Normal...");

IntStream range = IntStream.rangeClosed(1, 10);
range.forEach(System.out::println);

System.out.println("Parallel...");

IntStream range2 = IntStream.rangeClosed(1, 10);
range2.parallel().forEach(System.out::println);

}

}

Выход


Normal...
1
2
3
4
5
6
7
8
9
10

Parallel...
7
6
8
9
10
1
4
5
3
2

2. Collection.parallelStream ()

Еще один простой параллельный пример для печати a в z , Для сбора мы можем использовать parallelStream() ,

ParallelExample2.java


package com.csharpcoderr.java8;

import java.util.ArrayList;
import java.util.List;

public class ParallelExample2 {

public static void main(String[] args) {

System.out.println("Normal...");

List alpha = getData();
alpha.stream().forEach(System.out::println);

System.out.println("Parallel...");

List alpha2 = getData();
alpha2.parallelStream().forEach(System.out::println);

}

private static List getData() {

List alpha = new ArrayList<>();

int n = 97;  // 97 = a, 122 = z
while (n <= 122) {
char c = (char) n;
alpha.add(String.valueOf(c));
n++;
}

return alpha;

}

}

Выход


Normal...
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Parallel...
q
s
r
o
x
h
l
p
d
i
g
t
u
n
z
v
j
k
w
f
m
c
a
e
b
y

3. Поток работает в параллельном режиме?

3.1 Мы можем проверить это с isParallel()

ParallelExample3a.java


package com.csharpcoderr.java8;

import java.util.stream.IntStream;

public class ParallelExample3a {

public static void main(String[] args) {

System.out.println("Normal...");

IntStream range = IntStream.rangeClosed(1, 10);
System.out.println(range.isParallel());         // ложный
range.forEach(System.out::println);

System.out.println("Parallel...");

IntStream range2 = IntStream.rangeClosed(1, 10);
IntStream range2Parallel = range2.parallel();
System.out.println(range2Parallel.isParallel()); // правда
range2Parallel.forEach(System.out::println);

}

}

3.2 Или напечатайте текущее имя потока следующим образом:

ParallelExample3b.java


package com.csharpcoderr.java8;

import java.util.stream.IntStream;

public class ParallelExample3b {

public static void main(String[] args) {

System.out.println("Normal...");

IntStream range = IntStream.rangeClosed(1, 10);
range.forEach(x -> {
System.out.println("Thread : " + Thread.currentThread().getName() + ", value: " + x);
});

System.out.println("Parallel...");

IntStream range2 = IntStream.rangeClosed(1, 10);
range2.parallel().forEach(x -> {
System.out.println("Thread : " + Thread.currentThread().getName() + ", value: " + x);
});

}

}

Выход


Normal...
Thread : main, value: 1
Thread : main, value: 2
Thread : main, value: 3
Thread : main, value: 4
Thread : main, value: 5
Thread : main, value: 6
Thread : main, value: 7
Thread : main, value: 8
Thread : main, value: 9
Thread : main, value: 10

Parallel...
Thread : main, value: 7
Thread : main, value: 6
Thread : ForkJoinPool.commonPool-worker-5, value: 3
Thread : ForkJoinPool.commonPool-worker-7, value: 8
Thread : ForkJoinPool.commonPool-worker-5, value: 5
Thread : ForkJoinPool.commonPool-worker-5, value: 4
Thread : ForkJoinPool.commonPool-worker-3, value: 9
Thread : ForkJoinPool.commonPool-worker-5, value: 1
Thread : ForkJoinPool.commonPool-worker-7, value: 2
Thread : ForkJoinPool.commonPool-worker-9, value: 10

PS По умолчанию параллельные потоки используют `ForkJoinPool`

4. Расчет

4.1 Java 8 потоков для печати всех простых чисел до 1 миллиона:

ParallelExample4.java


package com.csharpcoderr.java8;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class ParallelExample4 {

public static void main(String[] args) {

long count = Stream.iterate(0, n -> n + 1)
.limit(1_000_000)
// .rallel () с этими 23 с, без этого 1 м 10 с
.filter(ParallelExample4::isPrime)
.peek(x -> System.out.format("%st", x))
.count();

System.out.println("nTotal: " + count);

}

public static boolean isPrime(int number) {
if (number <= 1) return false;
return !IntStream.rangeClosed(2, number / 2).anyMatch(i -> number % i == 0);
}

}

Результат:

  • Для обычных потоков это занимает 1 минуту 10 секунд.
  • Для параллельных потоков это занимает 23 секунды.

PS Протестировано с i7-7700, 16G RAM, Windows 10

4.2 Еще один пример параллельного потока для определения среднего возраста списка сотрудников.


List employees = obj.generateEmployee(10000);

double age = employees
.parallelStream()
.mapToInt(Employee::getAge)
.average()
.getAsDouble();

System.out.println("Average age: " + age);

5. Тематическое исследование

5.1 Параллельные потоки для повышения производительности трудоемких задач сохранения файлов.

Этот код Java сгенерирует 10000 случайных сотрудников и сохранит в 10000 файлов, каждый сотрудник сохранит в файл.

  • Для обычного потока это занимает 27-29 секунд.
  • Для параллельного потока это занимает 7-8 секунд.

PS Протестировано с i7-7700, 16G RAM, Windows 10

ParallelExample5.java


package com.csharpcoderr.java8;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ParallelExample5 {

private static final String DIR = System.getProperty("user.dir") + "/test/";

public static void main(String[] args) throws IOException {

Files.createDirectories(Paths.get(DIR));

ParallelExample5 obj = new ParallelExample5();

List employees = obj.generateEmployee(10000);

// нормальный, последовательный
//employees.stream().forEach(ParallelExample5::save); // 27-е-29-е

// параллельно
employees.parallelStream().forEach(ParallelExample5::save); // 7с-8с

}

private static void save(Employee input) {

try (FileOutputStream fos = new FileOutputStream(new File(DIR + input.getName() + ".txt"));
ObjectOutputStream obs = new ObjectOutputStream(fos)) {
obs.writeObject(input);
} catch (IOException e) {
e.printStackTrace();
}

}

private List generateEmployee(int num) {

return Stream.iterate(0, n -> n + 1)
.limit(num)
.map(x -> {
return new Employee(
generateRandomName(4),
generateRandomAge(15, 100),
generateRandomSalary(900.00, 200_000.00)
);
})
.collect(Collectors.toList());

}

private String generateRandomName(int length) {

return new Random()
.ints(5, 97, 122) // 97 = a, 122 = z
.mapToObj(x -> String.valueOf((char) x))
.collect(Collectors.joining());

}

private int generateRandomAge(int min, int max) {
return new Random()
.ints(1, min, max)
.findFirst()
.getAsInt();
}

private BigDecimal generateRandomSalary(double min, double max) {
return new BigDecimal(new Random()
.doubles(1, min, max)
.findFirst()
.getAsDouble()).setScale(2, RoundingMode.HALF_UP);
}

}

Employee.java


package com.csharpcoderr.java8;

import java.io.Serializable;
import java.math.BigDecimal;

public class Employee implements Serializable {

private static final long serialVersionUID = 1L;

private String name;
private int age;
private BigDecimal salary;

// геттеры, сеттеры и т.д ...

}

Рекомендации

Параллельный поток Java 8 параллельных простых чисел

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

0.00 (0%) 0 votes

ЧИТАТЬ ТАКЖЕ:  Затмение Ctrl + T в IntelliJ IDEA

ОСТАВЬТЕ ОТВЕТ

Пожалуйста, введите ваш комментарий!
пожалуйста, введите ваше имя здесь