undefined

Многопоточность или многонитевость

Java Core
6 уровень , 1 лекция
Открыта

— Привет, Амиго! У нас новая и очень трудная тема. Сочувствую. Часто она считается одной из самых сложных не только в Java, но и в программировании вообще. Это – многонитевость (multithreading).

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

Допустим, ты решил написать такую же игру. Твоей программе придется отслеживать команды управления (ввод с клавиатуры), перемещать звездолеты, рассчитывать их траектории и последствия столкновения, а также отрисовывать все это на экране пользователя. Это очень сложная работа.

Вспомни, как мы решили «проблему большой сложности» в том примере про рост курьерской компании.

— Мы разделили ее на независимые отделы и жестко задали (стандартизировали) способы их взаимодействия.

— Но что делать, когда независимым частям нужно выполнить какой-то объем работы, параллельно с другими частями?! Ответ на этот вопрос – нити(трэды) (или как их неправильно называют – потоки).

Попробуй представить программу, как такого маленького робота, который бегает по коду и выполняет команды. Сначала выполнил команду, написанную в одной строке, затем перешел на следующую, и так далее.

— Представил. Ничего сложного!

— Отлично. А теперь представь, что таких роботов у тебя несколько. И пока один занимается вводом от пользователя, второй меняет объекты в соответствии с ним. Третий выполняет код, по отображению этих объектов на экран, а четвертый несколько раз в секунду проверяет – не столкнулись ли корабли и, в случае столкновения, просчитывает его результаты.

Таким образом, мы можем разделить программу не только на независимые части/объекты, но и добиться того, что эти части будут выполнять свою работу независимо друг от друга. А чем меньше взаимодействия между отдельными частями, тем меньше сложность программы.

Представь, что ты смог заменить менеджера – скриптом, рассылающим письма. А остальные отделы компании об этом даже не догадались. Такие примеры уже имели место в 26 веке и показали отличные результаты. Большинство менеджеров, и даже топ-менеджеров, может быть успешно заменено скриптом средней сложности. Только после вмешательства «профсоюза офисного планктона» удалось остановить массовые увольнения менеджеров. Но это так – отвлечение от темы.

— Как интересно.

— Мало того, что в программе может быть несколько таких «маленьких роботов», исполняющих код, так эти роботы могут еще общаться друг с другом и порождать новых роботов.

— Порождать новых роботов?

— Да, для выполнения новых задач. Иногда выгодно создать еще одного робота (еще одну нить), которая будет выполнять какое-то действие одновременно с текущей нитью (роботом).

— Думаю, что это хорошая вещь, хоть пока не могу придумать, где бы я этим пользовался.

А почему это называется «нити»?

— Представь, что все роботы разного цвета, и каждый робот помечает своим цветом все команды, которые он выполнил. Таким образом, за маленьким роботом, как за карандашом, будет тянуться след. Этот след тянется за роботом, как нитка за иголкой.

У каждого такого «маленького робота» есть задание, для исполнения которого его создали. И нить – это набор команд, выполненных в процессе исполнения этого задания.

Допустим, ты летишь на звездолете, чтобы доставить груз. Тогда «доставить груз» — это твое задание, ты в процессе его исполнения. А путь, который ты пролетел – это твоя нить. Можно сказать, что каждому новому заданию, каждой еще не решенной задаче соответствует своя нить – путь, который еще предстоит пройти.

— Другими словами, есть задание и «маленький робот», который его исполняет, а нить – это всего лишь взгляд на текущее положение дел со стороны?

— Именно так.

А вот как все это работает глубоко внутри. Т.к. процессор у компьютера один, то он может выполнять только одну команду одновременно. Поэтому происходит вот что: процессор постоянно переключается между нитями. Переключился на новую нить, выполнил несколько ее команд, затем переключился на следующую нить, выполнил несколько ее команд и так далее. Но т.к. переключение между нитями происходит сотни раз в секунду, со стороны кажется, что все нити работают одновременно.

Многопоточность или многонитевость - 1
Комментарии (273)
Чтобы просмотреть все комментарии или оставить свой,
перейдите в полную версию
15 мая 2021
Я правильно понимаю, что многопоточность и многонитевость (и, соответственно, потоки и нити) это одни и те же понятия по сути, просто разные люди называют их по-разному? То есть нет другого какого-то явления/предмета/др., что бы называлось поток?
Сергей Коваленко 29 уровень, Краснодар
24 апреля 2021
2021 год - процессор может выполнять только одну команду одновременно. чет у меня глаз задергался 😵
Азатжан 16 уровень, Алматы
10 апреля 2021
Вот здесь я бросил заниматься программированием летом 2020 года. Пытаюсь вернуться опять. Чувствую что забыл многие темы.
Ринат 23 уровень, Казань
2 апреля 2021
Вот хороший перевод книги "Параллельное программирование в JAVA на практике" автор Брайан Гоетс. тык сюда
Арсений 32 уровень, Москва
24 марта 2021
У вас не болит голова, когда вы пытаетесь представить, как маленький i9 10900k размером с печеньку выполняет просто какие то невообразимые объемы вычислений, используя для этого электрические колебания(0-1) ? Это самое невероятное, что вообще создавал человек
Юлия 16 уровень
17 марта 2021
Может кому-то поможет это видео https://www.youtube.com/watch?v=0Cdsk2BeNA8
Сергей 18 уровень
11 марта 2021
авторы, вам не кажется что одноядерных процессоров давным-давно не существует даже в мобильном сегменте и ДЕЗИНФОРМАТИВНУЮ статью сбивающую людей с толку, давно пора переписать?
VasliyD 22 уровень, Москва
25 февраля 2021
"Вспомни, как мы решили «проблему большой сложности» в том примере про рост курьерской компании." Вообще не помню, где хоть это было? 🙈
Arman Tursynbek 17 уровень, Алматы
16 февраля 2021
Я бы для новичков представил многопоточность во так: Представьте что Процессор (с одним ядром) - это дракон с одной головой. Вот он сидел у себя в пещере и ел тушеную курицу с черносливом (это называется процессом - "Сидеть и есть"). Он услышал крики с улицы - к нему пришли сражаться люди (создается новый процесс - "Драка"). Его окружили четыре Ивана - братья-близнецы (четыре задачи). Что-бы ни один Иван не подошел слишком близко, Дракон переодически сражается с каждым Иваном: 1. Повернул голову на Ивана1, отрыгнул огнём. 2. Повернул голову на Ивана2, отрыгнул огнём. 3. Повернул голову на Ивана3 и т.д. Это - мнимая многопоточность: процессор всего лишь один, а задач много - и процессор постоянно переключается между задачами. (т.е. каждая задача - это поток, но все они - мнимые, не настоящие). А теперь представим что Дракон - четырехголовый (Процессор - с четырьмя ядрами). Как думаете, четыре головы против четырех Иванов эффективнее? Конечно, Процессор с одним ядром можно разогнать - увеличить частоту шины, подать больше напряжения (Дать одноголовому дракону энергетик). Но по эффективности он будет всё-равно хуже многоядрового процессора. Однако мнимая или настоящая многопоточность - программисту как-бы всё равно. Язык позволяет создать много потоков. P.S. Итак. Процесс - это фактически ваша программа. Процесс может порождать множество потоков (но обычно процесс имеет один поток - главный). P.S Это не мой текст. Автор - virex
Павел 26 уровень
11 февраля 2021
Хорошо разжеванные статейки по потокам (en) https://www.javatpoint.com/multithreading-in-java