1 Говоря о потоках, прежде всего, давайте поговорим о процессе.Следующее определение процесса:
Процесс — это основа структуры операционной системы, выполнение программы, действие, которое происходит, когда программа и ее структуры данных последовательно выполняются на процессоре, процесс, в котором программа работает с набором данных, и процесс распределения ресурсов и выделения ресурсов системой Независимая единица планирования.
Проще говоря, exe-файл, указанный в диспетчере задач, можно понимать как процесс, например, QQ.exe — это процесс, а процесс — это основная работающая единица, управляемая системой.
1.1 Что такое нить?
Поток — это наименьшая единица, которую операционная система может выполнять для планирования операций.Он включен в процесс и является фактической единицей операции в процессе.
Проще говоря, поток можно понимать как подзадачу, которая выполняется независимо в процессе. Например, при выполнении QQ.exe одновременно выполняется множество подзадач.
1.2 Разница между процессом и потоком
1.2.1 Планирование. Поток — это основная единица планирования и распределения, а процесс — это основная единица владения ресурсами.
1.2.2 Параллелизм. Одновременно могут выполняться не только процессы, но и несколько потоков одного и того же процесса.
1.2.3 Владение ресурсами: Процесс - это независимая единица, владеющая ресурсами.Сам поток в основном не владеет системными ресурсами, а имеет только некоторые ресурсы (такие как программные счетчики, набор регистров и стеков), которые необходимы для работы, но он может принадлежат одному и тому же Все ресурсы, принадлежащие процессу, совместно используются другими потоками процесса. Процессы не могут совместно использовать адресное пространство. Потоки совместно используют адресное пространство своего процесса.
1.2.4 Системные накладные расходы: когда вы создаете или отзываете процесс, из-за выделения и повторного использования ресурсов системы системные накладные расходы значительно превышают стоимость создания или отзыва потоков.
1.3 Что такое многопоточность?
Многопоточность — это выполнение нескольких потоков практически одновременно.
1.4 Зачем использовать многопоточность
1.4.1 Использование потоков может перевести задачи программы, которые занимают много времени, в фоновый режим для обработки.
1.4.2 Пользовательский интерфейс стал более привлекательным.Например, если пользователь нажимает кнопку, чтобы запустить обработку события, может появиться индикатор выполнения, отображающий ход обработки.
1.4.3 Операционная эффективность программы может быть улучшена.
1.4.4 Потоки более полезны при реализации некоторых ожидающих задач, таких как пользовательский ввод, чтение файлов и отправка и получение данных по сети.
2 Состояние потока
Вообще говоря, поток включает в себя следующие состояния: создание (новый), готовность (выполняемый), работающий (работает), блокирующий (заблокированный), timed_waiting, ожидание и мертвый (мертвый).
3 Как использовать многопоточность
3.1 Наследование класса Thread
Видно, что программа выполняется попеременно, но в итоге будет выполняться до 98.
3.2 Реализация интерфейса Runnable
Вы все еще можете видеть, что программа выполняется попеременно, но в конечном итоге она будет выполняться до 98.
3.3 Наследование и реализация интерфейса Callable
Здесь необходимо пояснить, что для реализации интерфейса Callable необходимо переписать метод call() и использовать класс FutureTask.
3.4 Использование пулов потоков, таких как среда Executor
Эта часть пока не будет представлена. Пул потоков обновления и Executor будут подробно описаны позже.
4 Обязательно ли использовать многопоточность быстрее?
Ответ: Не обязательно, потому что многопоточность будет выполнять переключение контекста, а переключение контекста приведет к накладным расходам.
4.1 Что такое переключение контекста?
Для одноядерного ЦП ЦП может одновременно запускать только один поток.Когда один поток запускается для запуска другого потока, это называется переключением контекста потока (аналогично процессам). Во время переключения контекста потока записываются такие данные, как счетчик программ и состояние регистров ЦП.
4.2 Как уменьшить переключение контекста?
4.2.1 Уменьшить количество потоков
Поскольку ЦП может одновременно выполнять только один поток, а мы хотим, чтобы программа выполнялась одновременно, операционная система должна постоянно выполнять переключение контекста, чтобы мы чувствовали, что программа выполняется параллельно. Следовательно, уменьшая количество потоков, мы можем уменьшить количество переключений контекста.
Однако, если количество потоков уже меньше количества ядер ЦП, и каждый ЦП выполняет один поток, само собой разумеется, что ЦП не нужно выполнять переключение контекста, но это не так.
4.2.2 Управление количеством потоков на одном замке
Если несколько потоков совместно используют одну и ту же блокировку, то когда один поток получает блокировку, другие потоки будут заблокированы; когда поток снимает блокировку, операционная система выбирает для выполнения один из заблокированных потоков, и снова происходит переключение контекста.
Следовательно, уменьшение количества потоков в одной и той же блокировке может также уменьшить количество переключений контекста.
4.2.3 Использование параллельного программирования без блокировок
Задачи, которые должны выполняться одновременно, не имеют состояния: сегментация HASH.
Так называемый stateless означает, что одновременно выполняемые задачи не имеют общих переменных, все они выполняются независимо. Для этого типа задач сегментация HASH может выполняться по идентификатору, и каждый сегмент выполняется потоком.
Задачи, которые должны выполняться одновременно, имеют состояние: алгоритм CAS
Если задаче необходимо модифицировать разделяемую переменную, то необходимо контролировать порядок выполнения потоков, иначе возникнут проблемы с безопасностью. Вы можете заблокировать задачу, чтобы обеспечить атомарность и видимость задачи, но это вызовет блокировку и вызовет переключение контекста, чтобы избежать переключения контекста, вы можете использовать алгоритм CAS, Используйте алгоритм CAS для обновления общей переменной только тогда, когда потоку необходимо обновить общую переменную.Этот метод не блокирует поток и гарантирует безопасность процесса обновления.
5 недостатков использования многопоточности:
5.1 Накладные расходы на переключение контекста
когда ЦПУ При переключении с выполнения потока на выполнение другого потока ему необходимо сначала сохранить локальные данные, указатель программы и т. д. текущего потока, а затем загрузить локальные данные, указатель программы и т. д. другого потока и, наконец, запустить исполнение. Этот переключатель называется «переключатель контекста». ЦПУ Будет выполнять поток в одном контексте, а затем переключаться на другой контекст для выполнения другого потока. Переключение контекста недешево. Переключения контекста должны быть сокращены, если в этом нет необходимости.
5.2 Увеличение потребления ресурсов
Потоки должны получать некоторые ресурсы от компьютера, когда они работают. В дополнение к ЦП потоку также требуется память для обслуживания своего локального стека. Это также требует некоторых ресурсов в операционной системе для управления потоками.
5.3 Программирование сложнее
Когда несколько потоков обращаются к общим данным, следует учитывать вопросы безопасности потоков.
6 Безопасность потоков
6.1 Определение безопасности потоков
Класс потокобезопасен, если его можно безопасно вызывать из нескольких потоков.
6.2 Классификация резьбовой безопасности
Безопасность потоков не является истинным или ложным утверждением.Общие данные можно разделить на следующие пять категорий в соответствии с порядком безопасности:
Неизменный, абсолютно потокобезопасный, относительно потокобезопасный, потокосовместимый и потокопротивоположный.
6.2.1 Неизменяемый
Неизменяемые объекты должны быть потокобезопасными. Независимо от реализации метода объекта или вызывающей стороны метода нет необходимости предпринимать какие-либо меры по потокобезопасности. Пока неизменяемый объект построен правильно, его внешне видимое состояние никогда не изменится, и он никогда не будет замечен в несогласованном состоянии в нескольких потоках.
Неизменяемые типы: базовые типы данных, измененные ключевым словом final; String; перечисляемые типы.;Некоторые подклассы Number, такие как типы числовых оболочек, такие как Long и Double, и типы больших данных, такие как BigInteger и BigDecimal. Но атомарные классы AtomicInteger и AtomicLong, оба подтипа Number, не являются неизменяемыми.
6.2.2 Абсолютная безопасность потока
Независимо от среды выполнения вызывающему объекту не требуются дополнительные меры синхронизации.
6.2.3 Безопасность относительной резьбы
Относительная потокобезопасность должна гарантировать, что отдельные операции над этим объектом являются потокобезопасными, и при вызове не требуется никаких дополнительных мер защиты, но для некоторых последовательных вызовов в определенном порядке может потребоваться использование дополнительных методов синхронизации на вызывающей стороне. , Гарантия правильности вызова.
6.2.4 Совместимость резьбы
Совместимость с потоками означает, что сам объект не является потокобезопасным, но правильное использование средств синхронизации на вызывающей стороне может гарантировать безопасное использование объекта в параллельной среде.Мы обычно говорим, что класс не является потокобезопасным, но чаще всего относится к этому делу. Джава Большинство классов API совместимы с потоками, например классы коллекций ArrayList и HashMap, соответствующие предыдущим классам Vector и HashTable. Ждать.
6.2.5 Противостояние потоков
Противодействие потокам относится к коду, который нельзя использовать одновременно в многопоточной среде, независимо от того, принимает ли вызывающая сторона меры синхронизации. Поскольку язык Java по своей природе является многопоточным, код оппозиции потокам, который исключает многопоточность, встречается редко и обычно вреден, и его следует по возможности избегать.