существуетЕсли кто-то спросит вас, что такое модель памяти Java, пришлите ему эту статью.Мы представили, что для решения проблем атомарности, видимости и упорядочения в параллельном программировании язык Java предоставляет ряд ключевых слов, связанных с параллельной обработкой, таких какsynchronized
,volatile
,final
,concurren包
Ждать.
В «Глубоком понимании виртуальной машины Java» есть такой отрывок:
synchronized
Ключевые слова можно использовать как одно из решений, когда требуются все три свойства атомарности, видимости и упорядоченности, и оно кажется «универсальным». Действительно, большинство одновременных операций управления можно выполнить с помощью synchronized.
Хемингуэй сказал в своей «Смерти после полудня»: «Движение айсберга величественно, потому что он составляет лишь одну восьмую часть воды».synchronized
Это просто ключевое слово, им легко пользоваться. Причина, по которой мы можем решать проблемы многопоточности, не задумываясь, заключается в том, что это ключевое слово помогает нам скрыть множество деталей.
Тогда эта статья оsynchronized
развернуть, основное введениеsynchronized
использование,synchronized
принцип, иsynchronized
Как обеспечить атомарность, видимость и гарантии порядка и т. д.
Использование синхронизированного
synchronized
это ключевое слово для управления параллелизмом, предоставляемое Java. Существует два основных варианта использования: синхронизированные методы и синхронизированные блоки кода. Это,synchronized
Вы можете декорировать как методы, так и блоки кода.
/**
* @author Hollis 18/08/04.
*/
public class SynchronizedDemo {
//同步方法
public synchronized void doSth(){
System.out.println("Hello World");
}
//同步代码块
public void doSth1(){
synchronized (SynchronizedDemo.class){
System.out.println("Hello World");
}
}
}
одеялоsynchronized
Доступ к измененным блокам кода и методам может осуществляться только одним потоком за раз.
Принцип реализации синхронизированного
synchronized
, является очень важным ключевым словом в Java для разрешения доступа к синхронизации данных в параллельных ситуациях. Когда мы хотим гарантировать, что общий ресурс доступен только одному потоку за раз, мы можем использовать его в нашем коде.synchronized
Ключевое слово блокирует класс или объект.
существуетГлубокое понимание многопоточности (1) - принцип реализации SynchronizedВ целях обеспечения целостности знаний я кратко представлю его здесь, а подробности можно прочитать в исходном тексте.
Декомпилируем приведенный выше код, можем получить следующий код:
public synchronized void doSth();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Hello World
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
public void doSth1();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: ldc #5 // class com/hollis/SynchronizedTest
2: dup
3: astore_1
4: monitorenter
5: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
8: ldc #3 // String Hello World
10: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
13: aload_1
14: monitorexit
15: goto 23
18: astore_2
19: aload_1
20: monitorexit
21: aload_2
22: athrow
23: return
Это видно из декомпилированного кода: Для метода синхронизации JVM принимаетACC_SYNCHRONIZED
маркер для достижения синхронизации. Для синхронизированных кодовых блоков. JVM используетmonitorenter
,monitorexit
Две инструкции для достижения синхронизации.
существуетThe Java® Virtual Machine SpecificationЕсть введение в принцип реализации методов синхронизации и блоков кода синхронизации, которое я перевожу на китайский язык следующим образом:
Синхронизация на уровне метода является неявной. В постоянном пуле синхронизированного метода будет один
ACC_SYNCHRONIZED
логотип. Когда поток хочет получить доступ к методу, он проверяет, существует лиACC_SYNCHRONIZED
, если есть настройка, вам нужно сначала получить блокировку монитора, затем начать выполнение метода и снять блокировку монитора после выполнения метода. В это время, если другие потоки запросят выполнение метода, они будут заблокированы, поскольку блокировка монитора не может быть получена. Стоит отметить, что если во время выполнения метода возникает исключение, и оно не обрабатывается внутри метода, блокировка монитора будет автоматически снята до того, как исключение будет выброшено за пределы метода.Использование синхронизированного блока кода
monitorenter
иmonitorexit
Реализованы две инструкции. может выполнитьmonitorenter
Инструкция понимается как блокировка, выполнениеmonitorexit
Это понимается как снятие блокировки. Каждый объект поддерживает счетчик количества раз, когда он был заблокирован. Этот счетчик разблокированных объектов равен 0, когда поток получает блокировку (выполняетmonitorenter
), счетчик увеличивается до 1, и когда тот же поток снова получает блокировку объекта, счетчик снова увеличивается. Когда тот же поток освобождает блокировку (выполняетсяmonitorexit
инструкция), счетчик снова уменьшается. когда счетчик равен 0. Блокировка будет снята, и другие потоки смогут получить блокировку.
Будь тоACC_SYNCHRONIZED
все ещеmonitorenter
,monitorexit
Все они реализованы на базе Monitor.В виртуальной машине Java (HotSpot) Monitor реализован на основе C++ и реализуется ObjectMonitor.
В классе ObjectMonitor предусмотрено несколько методов, таких какenter
,exit
,wait
,notify
,notifyAll
Ждать.sychronized
При блокировке будет вызываться метод ввода объекта objectMonitor, а при разблокировке — метод выхода. (Подробнее о монитореГлубокое понимание многопоточности (4) - принцип реализации Monitor)
синхронизация и атомарность
Атомарность означает, что операция непрерывна и должна выполняться полностью или не выполняться вообще.
мы вВ чем проблема многопоточности в параллельном программировании на Java?Проанализировано в: Поток является базовой единицей планирования ЦП. ЦП имеет концепцию кванта времени и будет планировать потоки в соответствии с различными алгоритмами планирования. Когда поток начинает выполняться после получения кванта времени, после того, как квант времени исчерпан, он теряет право использовать ЦП. Таким образом, в многопоточном сценарии проблемы с атомарностью будут возникать, поскольку временные срезы чередуются между потоками.
В Java, чтобы гарантировать атомарность, предоставляются две высокоуровневые инструкции байт-кода.monitorenter
иmonitorexit
. Как упоминалось ранее, соответствующие ключевые слова в Java для этих двух инструкций байт-кода:synchronized
.
пройти черезmonitorenter
иmonitorexit
инструктаж, который гарантированноsynchronized
Модифицированный код может быть доступен только одному потоку за раз и не может быть доступен другим потокам, пока блокировка не будет снята. Итак, в Java вы можете использоватьsynchronized
чтобы гарантировать атомарность операций внутри методов и блоков кода.
Поток 1 выполняется
monitorenter
Когда инструкция выполняется, монитор будет заблокирован, и другие потоки не смогут получить блокировку после блокировки, если поток 1 активно не разблокирует его. Даже во время выполнения поток 1 по какой-то причине освобождает ЦП, например, из-за исчерпания кванта времени ЦП, но не разблокируется. И из-заsynchronized
Блокировка является реентерабельной, и следующий временной интервал может быть получен только сам по себе или будет продолжать выполнять код. пока весь код не будет выполнен. Это гарантирует атомарность.
синхронизация и видимость
Видимость означает, что когда несколько потоков обращаются к одной и той же переменной, один поток изменяет значение переменной, а другие потоки могут сразу увидеть измененное значение.
мы вЕсли кто-то спросит вас, что такое модель памяти Java, пришлите ему эту статью.Проанализировано в: Модель памяти Java предусматривает, что все переменные хранятся в основной памяти, каждый поток имеет свою собственную рабочую память, а рабочая память потока сохраняет копию основной памяти, копию переменных, используемых в потоке, Все операции над переменными потоком должны выполняться в рабочей памяти и не могут напрямую читать или записывать в основную память. Разные потоки не могут напрямую обращаться к переменным в рабочей памяти друг друга, а передача переменных между потоками требует синхронизации данных между их собственной рабочей памятью и основной памятью. Поэтому может случиться так, что поток 1 изменяет значение переменной, а поток 2 невидим.
Как мы упоминали ранее,synchronized
Измененный код будет заблокирован в начале выполнения и разблокирован после выполнения. Для обеспечения видимости существует правило, что перед разблокировкой переменной переменная должна быть синхронизирована обратно в основную память. После этой разблокировки последующие потоки могут получить доступ к измененному значению.
Таким образом, значение объекта, заблокированного ключевым словом synchronized, видно.
синхронизировано и заказано
Порядок означает, что порядок выполнения программы соответствует порядку кода.
мы вЕсли кто-то спросит вас, что такое модель памяти Java, пришлите ему эту статью.Анализ в: В дополнение к введению временных интервалов, из-за оптимизации процессора и перестановки инструкций, ЦП также может выполнять неупорядоченное выполнение входного кода.Например, загрузка->добавить->сохранить может быть оптимизировано для загрузить->сохранить->добавить. Здесь могут возникнуть проблемы с заказом.
Здесь следует отметить, что,synchronized
Невозможно отключить переупорядочивание инструкций и оптимизацию процессора. Это,synchronized
Упомянутых выше проблем не избежать.
Так почему ты говоришьsynchronized
Также предоставляет гарантию заказа?
Это немного расширяет концепцию заказа. Естественное упорядочение в программах на Java можно описать одним предложением: если оно наблюдается в этом потоке, все операции упорядочены естественным образом. Если один поток наблюдает за другим потоком, все операции выполняются не по порядку.
Приведенное выше предложение также является исходным предложением в «Глубоком понимании виртуальной машины Java», но как его понять? Чжоу Чжимин подробно не объяснил. Здесь я просто расширяю, это фактически то же самое, что иas-if-serial语义
Связанный.
as-if-serial
Семантика означает: как бы ни переупорядочивались (компилятор и процессор для улучшения параллелизма), результат выполнения однопоточной программы изменить нельзя. Компиляторы и процессоры, как бы они ни оптимизировали, должны подчинятьсяas-if-serial
семантика.
неправильно здесьas-if-serial语义
Подробно раскрыто, проще говоря,as-if-serial语义
Гарантируется, что существуют определенные ограничения на перестановку инструкций в одном потоке, и пока компилятор и процессор соблюдают эту семантику, можно считать, что однопоточная программа выполняется последовательно. Конечно, на самом деле перестановка есть, но нам не нужно заботиться о помехах этой перестановки.
Потому, чтоsynchronized
Доступ к измененному коду может быть получен только одним и тем же потоком в одно и то же время. Затем он выполняется в одном потоке. Таким образом, его упорядоченность может быть гарантирована.
синхронизированная и блокировка оптимизации
ранее представленныйsynchronized
Использование, принцип и эффект параллельного программирования. очень полезное ключевое слово.
synchronized
На самом деле это реализовано с помощью Monitor, при блокировке будет вызываться ObjectMonitor.enter
метод, который будет вызываться при разблокировкеexit
метод. На самом деле, только до JDK1.6 синхронизированная реализация будет напрямую вызывать ObjectMonitor.enter
иexit
, такой замок называется тяжеловесным замком.
Поэтому в JDK1.6 было сделано много оптимизаций для блокировок, а затем появились облегченные блокировки, предвзятые блокировки, устранение блокировок, адаптивные спин-блокировки и огрубление блокировки (спин-блокировки доступны в версии 1.4, но по умолчанию отключены). off, jdk1.6 включен по умолчанию), эти операции предназначены для более эффективного обмена данными между потоками и решения проблемы конкуренции.
Информацию о спин-блокировках, укрупнении блокировки и устранении блокировки см.Глубокое понимание многопоточности (5) - технология оптимизации блокировок виртуальной машины Java, Что касается облегченных замков и смещенных замков, то они уже находятся в планировании графика. Позже я представлю отдельную статью, которая будет эксклюзивно опубликована в моем блоге (http://www.hollischuang.com) и публичном аккаунте (Hollis), быть в курсе.
хорошо, оsynchronized
Ключевое слово, мы представили его использование, принцип и то, как обеспечить атомарность, последовательность и видимость, а также расширенную информацию и размышления об оптимизации блокировки. Позже мы продолжим знакомитьvolatile
ключевые слова и он иsynchronized
разница и т.д. Быть в курсе.