Давайте посмотрим правде в глаза, многопоточная работа в 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 Listdata; 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(){ Listdata = 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”