Если кто-то спросит вас, что такое synchronized, пришлите ему эту статью.

Java задняя часть JVM переводчик

существуетЕсли кто-то спросит вас, что такое модель памяти 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разница и т.д. Быть в курсе.

wechat