Иногда оптимизация компиляторов и процессоров вызывает отличие время выполнения от того, что мы представляли. По этой причине Java ввела некоторые ограничения на компиляторы и процессоры. Модель памяти Java (JMM) абстрагирует их, так что нет необходимости рассматривать так много основных деталей при написании кода, и гарантирует, что «до тех пор, пока вы следуете правилам JMM, чтобы написать программу, результат выполнения должен быть правильным».
Абстрактная структура JMM
В Java все экземпляры и статические переменные хранятся в памяти кучи, которую можно разделить между потоками, и эта часть также называется общими переменными . Локальные переменные, параметры определения метода и параметры обработки исключений находятся на стеке, а память стека не обменивается по потокам.
Однако из -за оптимизации компилятора и процессора возникнут проблемы с видимостью с общими переменными. Например, в многопроцессорах потоки могут быть выполнены на разных процессорах, а кэш, несовместимый между процессорами, вызовет проблемы видимости с общими переменными . Возможно, что два потока видят разные значения одной и той же переменной.
JMM Abstracts Оптимизации, сделанные этим оборудованием, в то, что каждый поток имеет локальную память. Когда вам нужно читать и написать общие переменные, скопируйте копию из основной памяти в локальную память. При написании общих переменных сначала напишите их в локальную память, а затем обновите их в основную память в будущем. Когда общая переменная снова читается, она будет прочитан только из локальной памяти.
Таким образом, связь между потоками требует двух шагов:
Запись по ветру: обновите локальную память и прочитайте поток: прочитайте обновленное значение из основной памяти
Таким образом, есть задержка между письмом и чтением: когда локальная память будет обновлена в основной памяти? Это приводит к проблемам видимости, и разные потоки могут видеть разные общие переменные.
случается, прежде чем
Буквально случается, прежде чем означает «до этого до этого». Это правило, которое Java формулирует по порядку выполнения программы, и должна соблюдаться синхронизация. Таким образом, программисты должны только выписывать правильную синхронную программу, и это происходит перед тем, что результаты работы не будут неправильными.
A Spect-Before B не только означает, что A выполняется до B, но также означает, что результат выполнения A виден для B, что обеспечивает видимость.
A Sodate-Before B, A не должен быть выполнен до B. Если AB чередование и результаты выполнения все еще верны, компилятору и процессору разрешается оптимизировать повторный порядок. Таким образом, до тех пор, пока результаты программы верны, нет проблем с тем, как компилятор и процессор оптимизируют и переупорядочивают его, и все это хорошо.
случается, прежде чем правила
Правила последовательности программ: в потоке правила блокировки операции после предыдущей операции происходит до: для той же блокировки, разблокировка происходит до того, как заблокируйте правила летучих доменов: запишите летучую переменную и прочитайте любую из летучих переменных после того, как произойдет. Транзитивность операции: A Tear-Before B, B, B происходит-до C, тогда A Speed-Before C start () Правила: если потоковое значение a выполняет threadb.start (), то Threadb.Start ().
Следующий пример помогает понять
Double Pi = 3,14; // Aduble r = 1,0; // bdouble aea = pi * r * r; // c
Вот три отношения, потому что правила 1 и 2-правила заказа программы, а правила 3 получены из переходных правил:
A sece-before bb случается, потому что Ca происходит, потому что до C
С зависит от A и B, но ни A, ни B не зависят от этого. Таким образом, даже если A и B будут переупорядочены, результаты выполнения не изменятся. В этом переупорядочении JMM работает.
Следующие две последовательности выполнения верны.
Выше приведено весь контент, который мы собрали для вас, об обучении модели памяти Java JMM. Для получения дополнительных вопросов, пожалуйста, оставьте сообщение ниже, чтобы обсудить. Спасибо за поддержку Wulin.com.