0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Теги: java, start(), run(), main(), stack, многопоточность, race condition, memory consistency errors</p>
1
<p>Теги: java, start(), run(), main(), stack, многопоточность, race condition, memory consistency errors</p>
2
<p>Принято считать, что многопоточность (<strong>multithreading</strong>) - одна из самых сложных тем в программировании. Давайте разберёмся, почему так много разработчиков делают ошибки при создании приложений, которые работают более чем в одном потоке.</p>
2
<p>Принято считать, что многопоточность (<strong>multithreading</strong>) - одна из самых сложных тем в программировании. Давайте разберёмся, почему так много разработчиков делают ошибки при создании приложений, которые работают более чем в одном потоке.</p>
3
<h2>Начнём с простого</h2>
3
<h2>Начнём с простого</h2>
4
<p>Что такое поток в Java? Как и всё остальное, поток в Java - это объект. Создать объект потока совсем не сложно:</p>
4
<p>Что такое поток в Java? Как и всё остальное, поток в Java - это объект. Создать объект потока совсем не сложно:</p>
5
Thread thread = new Thread();<p>Что в этом объекте особенного? У него есть методы<strong>start()</strong>и<strong>run()</strong>. Например, если в методе<strong>main()</strong>вызвать у объекта потока метод<strong>start()</strong>, то через некоторое время у него будет вызван метод<strong>run()</strong>. И этот вызов будет иметь новый<strong>Stack</strong>и команды метода<strong>run()</strong>могут быть выполнены физически в одно и тоже время, что и команды метода<strong>main()</strong>.</p>
5
Thread thread = new Thread();<p>Что в этом объекте особенного? У него есть методы<strong>start()</strong>и<strong>run()</strong>. Например, если в методе<strong>main()</strong>вызвать у объекта потока метод<strong>start()</strong>, то через некоторое время у него будет вызван метод<strong>run()</strong>. И этот вызов будет иметь новый<strong>Stack</strong>и команды метода<strong>run()</strong>могут быть выполнены физически в одно и тоже время, что и команды метода<strong>main()</strong>.</p>
6
<p>То есть… в другом потоке. И в этом первая сложность многопоточности: поток - это объект и в то же время поток - это последовательность команд. Команд метода<strong>run()</strong>объекта потока.</p>
6
<p>То есть… в другом потоке. И в этом первая сложность многопоточности: поток - это объект и в то же время поток - это последовательность команд. Команд метода<strong>run()</strong>объекта потока.</p>
7
<p>Вторая сложность многопоточности в непредсказуемости порядка некоторых событий. Допустим вы создали 10 новых потоков, пронумеровали их и вызвали у них методы<strong>start()</strong>. Будут ли методы<strong>run()</strong>этих объектов выполнены в той же последовательности, что вы задали при нумерации?</p>
7
<p>Вторая сложность многопоточности в непредсказуемости порядка некоторых событий. Допустим вы создали 10 новых потоков, пронумеровали их и вызвали у них методы<strong>start()</strong>. Будут ли методы<strong>run()</strong>этих объектов выполнены в той же последовательности, что вы задали при нумерации?</p>
8
<p>На самом деле нет. Значит, в какой последовательности будут выполнены методы<strong>run()</strong>, решает… операционная система. И у вас есть только очень опосредованные способы влияния на порядок выполнения (например, через приоритеты).</p>
8
<p>На самом деле нет. Значит, в какой последовательности будут выполнены методы<strong>run()</strong>, решает… операционная система. И у вас есть только очень опосредованные способы влияния на порядок выполнения (например, через приоритеты).</p>
9
<h2>Взаимодействие потоков</h2>
9
<h2>Взаимодействие потоков</h2>
10
<p>Если у вас есть задача, которую можно сделать в отдельном потоке, не дожидаясь её завершения и игнорируя её результат (например: записать что-то в лог; послать по UDP данные; обработать запрос пользователя, прочитать ответ в базе и отправить пользователю), то многопоточность - легко и весело.</p>
10
<p>Если у вас есть задача, которую можно сделать в отдельном потоке, не дожидаясь её завершения и игнорируя её результат (например: записать что-то в лог; послать по UDP данные; обработать запрос пользователя, прочитать ответ в базе и отправить пользователю), то многопоточность - легко и весело.</p>
11
<p>Проблемы начинаются когда несколько потоков хотят взаимодействовать между собой через общую память. Например, если один поток пишет данные, а другой читает. То есть, один меняет общий объект, а второй, в это же время, обращается к полям общего объекта.</p>
11
<p>Проблемы начинаются когда несколько потоков хотят взаимодействовать между собой через общую память. Например, если один поток пишет данные, а другой читает. То есть, один меняет общий объект, а второй, в это же время, обращается к полям общего объекта.</p>
12
<p>Ошибки приложения, которые при этом происходят, относят к одному из двух типов:<strong>race condition</strong>и<strong>memory consistency errors</strong>. Что это, и как с ними бороться, мы рассмотрим чуть позже.</p>
12
<p>Ошибки приложения, которые при этом происходят, относят к одному из двух типов:<strong>race condition</strong>и<strong>memory consistency errors</strong>. Что это, и как с ними бороться, мы рассмотрим чуть позже.</p>
13
<p><em>Есть вопрос? Напишите в комментариях!</em></p>
13
<p><em>Есть вопрос? Напишите в комментариях!</em></p>
14
14