Давайте посмотрим правде в глаза, многопоточная работа в Java – это Тяжело 😔
- Вы должны объявить класс, который реализует Runnable.
- Затем переопределите метод run.
- И, если вы хотите передать некоторые параметры потоку, вы должны включить их в конструктор класса.
- И да, если у вас есть данные, которые вы хотите обрабатывать по частям, вам также придется разделять данные самостоятельно.
Давайте рассмотрим пример. 🤔
Допустим, у нас есть список строк, которые мы хотим обрабатывать по частям, каждый в отдельном потоке, чтобы ускорить работу.
Процесс, который мы хотим применить ⚒
class Service{
public void doWork(String s){
System.out.printf("Do work on %s%n", s);
}
}
Класс thread, реализующий Runnable ⚙️
class Job implements Runnable{
private final List data;
private final Service service;
public Job(List data) {
this.data = data;
this.service = new Service();
}
@Override
public void run() {
for (String s : data)
service.doWork(s);
}
}
И это код, чтобы все это произошло 🔗
// get the data chunks and run a separate worker thread for each chunk
public void oldWay(){
List data = getData();
for(List batch : getDataChunks(data, 1000))
new Job(batch).run();
}
// get the numbers from 0 to 10,000 as Strings
private List getData(){
return IntStream.
range(0, 10_000).
mapToObj(Integer::toString).
collect(Collectors.toList());
}
private List> getDataChunks(List data, int chunkSize){
List> result= new ArrayList<>();
final AtomicInteger counter = new AtomicInteger();
for (String s : data) {
if (counter.getAndIncrement() % chunkSize == 0)
result.add(new ArrayList<>());
result.get(result.size() - 1).add(s);
}
return result;
}
Это Была Большая Ручная Работа 🤕
Пришло Время Нам Встретиться С Параллельным Потоком. 🥳🥳
👉 что это?
- According to Oracle:
Когда поток выполняется параллельно, среда выполнения Java разбивает поток на несколько подпотоков. Агрегатные операции повторяют и обрабатывают эти подпотоки параллельно, а затем объединяют результаты
👉 Как Это Работает?
Когда мы вызываем parallel Stream для коллекции, мы получаем несколько подпотоков, каждый из которых работает в отдельном потоке. Каждый поток обрабатывает несколько элементов из коллекции.
👉 Сколько потоков задействовано в работе?
Это зависит от вашей конфигурации.
Размер по умолчанию равен на единицу меньше, чем количество ядер вашего процессора.
Этот размер общего пула по умолчанию можно изменить с помощью этого свойства
Java.util.concurrent. ForkJoinPool.common.parallelism=8
Вы также можете использовать свой собственный пользовательский пул потоков.
Давайте Рассмотрим Пример 👀
public void newWay(){
Service service = new Service();
// note that we used the getData method and Service class from previous example
getData().parallelStream().forEach(service::doWork);
}
Намного Лучше 😍
Код На GitHub 👨🏻 💻
Проверьте мой учебник по потокам Java 👈
Оригинал: “https://dev.to/jarjanazy/make-life-easy-using-java-parallel-streams-bk1”