Глава длинная и сложная, поэтому разобью на две части. Заметки:
- В многопоточке есть проблема, что код может выглядеть нормально, но с повышенной нагрузкой всё сломается.
- Многопоточный код помогает отделить выполняемую операцию от момента ее выполнения.
- Отделение "что" и "когда" способно кардинально улучшить производительность и структуру приложения.
- Дальше целая большая страница про то, что многопоточность — это очень важно и полезно.
- Многопоточность всегда сопряжена с определенными затратами (время, производительность, силы, нервы).
- Правильная реализация сложна даже для простых задач.
- Ошибки многопоточности обычно плавающие и не воспроизводятся, поэтому они часто игнорируются как случайные.
- Многопоточность часто требует фундаментальных изменений в проектировании.
- Нужно понимать как компилятор обрабатывает сгенерированный байт-код и разбираться в том, какие операции рассматриваются моделью памяти Java как атомарные. Вот это я, кстати, никогда не рассматривала и не интересовалась. Надо будет поизучать.
- Всегда помните принцип единственной ответственности. Класс/метод/что угодно имеют только одну причину для изменения. Отделяйте код, относящийся к многопоточности, от остального кода.
- Чем больше в коде мест, где используются общие данные, тем с большей вероятностью вы где-то забудете поставить synchronized, что приведет к нарушению работы. И в этом случае велик шанс дублирования. Также будет труднее найти источник сбоя.
- Как правило копирование каких-то объектов позволяет избежать синхронизации в коде. Экономия на защитных блокировках окупит затраты на создание объектов и уборку мусора.
- Потоки должны быть как можно более независимы. Каждый поток в идеале работает в своем независимом мире со своими локальными переменными.
- Используйте потоко-безопасные коллекции. Удивительно, но ConcurrentHashMap почти всегда работает лучше HashMap.
Мифы многопоточности:
- Многопоточность всегда повышает быстродействие. Это актуально только при большом времени ожидания, которое могли бы использовать более эффективно другие потоки.
- Написание многопоточного кода не изменяет архитектуру программы. Архитектура многопоточной и однопоточной программы сильно отличаются.
- При работе с контейнером (веб-контейнер или что-то джавовое) разбираться в проблемах многопоточного программирования не обязательно. Тоже не так. Желательно знать как все работает, чтобы защититься от проблем обновления и взаимных блокировок.