Механизм блокировки Java для понимания

Java задняя часть Операционная система Java EE

предисловие

Оглядываясь назад на фронт:

Только лысая голова может стать сильнее!

В этой статье в основном рассказывается о многопоточности Java.запорный механизм, есть два вида:

  • Synchronized
  • Явная блокировка

Должен сказать несколько слов:

  • В «Java Core Technology Volume 1» мы сначала говорим о более сложной явной блокировке, а затем говорим о более простой синхронизированной блокировке.
  • И «Практика параллельного программирования на Java» объяснила синхронизацию в первых 4 главах и поместила явную блокировку в 13 главах.

фактическибольше ямы, Если вы можете сначала рассказать о механизме блокировки Synchronized, а затем поговорить о механизме блокировки явной блокировки, это будет легко понять. Вам также не нужно охватывать столько глав.

Тогда начнем~

Один, синхронизированный замок

1.1 Что такое синхронизированная блокировка?

синхронизированный - это Javaключевые слова, оно можеткодовый блок (метод) заблокирован

  • Его очень просто использовать, если вы добавите синхронизированное ключевое слово в блок кода (метод), вы можетедобиться синхронизациифункция~

    public synchronized void test() {
        // 关注公众号Java3y
        // doSomething
    }

синхронизированный - этоМьютекс

  • Только один поток за раз может войти в заблокированный блок кода.

синхронизированный - этоВстроенный замок/блокировка монитора

  • Явакаждый объектИмеетсяВстроенный замок (монитор, также можно понимать как метку замка), а синхронизация заключается в использовании встроенной блокировки (монитора) объекта для блокировки блока кода (метода)!

1.2 Какая польза от синхронизированного?

  • синхронизированный гарантирует, что потокатомарность. (Защищенный блок кода выполняется один раз, ни один поток не будет обращаться к нему одновременно)
  • синхронизированный также гарантируетвидимость. (После выполнения synchronized измененная переменная видна другим потокам)

Синхронизация в Java реализует синхронизацию переменных с помощью встроенных блокировок, а затем реализуетАтомарность операций над переменными и видимость переменных другими потоками, тем самым обеспечивая безопасность потоков в параллельных ситуациях.

1.3 Принцип синхронного

Давайте сначала посмотрим на фрагмент кода, который изменяет синхронизированный метод и блок кода:


public class Main {
	//修饰方法
    public synchronized void test1(){

    }

	
    public void test2(){
		// 修饰代码块
        synchronized (this){

        }
    }
}

Декомпилируем и смотрим:

Блок синхронизированного кода:

  • Реализуется инструкциями monitorenter и monitorexit.

Синхронный метод(Я не вижу здесь, что вам нужно смотреть на базовую реализацию JVM)

  • Реализация ACC_SYNCHRONIZED для модификаторов метода.

Синхронизированный нижний слойЧерез объект монитора объект имеет свой собственный заголовок объекта и хранит много информации, одна из которых указывает, какой поток им удерживается..

Для получения подробной информации см.:

1.4 Как использовать синхронизированный

Synchronized обычно мы используем для изменения трех вещей:

  • Модифицированные обычные методы
  • декорированный кодовый блок
  • Украсьте статические методы

1.4.1 Изменить общие методы:

Используемый замокОбъект Java3y (встроенная блокировка)


public class Java3y {


    // 修饰普通方法,此时用的锁是Java3y对象(内置锁)
    public synchronized void test() {
        // 关注公众号Java3y
        // doSomething
    }

}

1.4.2 Модифицированный кодовый блок:

Используемый замокОбъект Java3y (встроенная блокировка)--->this


public class Java3y {
    
    public  void test() {
        
        // 修饰代码块,此时用的锁是Java3y对象(内置锁)--->this
        synchronized (this){
            // 关注公众号Java3y
            // doSomething
        }
    }
}

Конечно, мы не обязательно используем это, когда используем synchronized для изменения блоков кода, мы также можемИспользовать другие объекты (любой объект имеет встроенный замок)

Итак, мы можем сделать это:

public class Java3y {


    // 使用object作为锁(任何对象都有对应的锁标记,object也不例外)
    private Object object = new Object();


    public void test() {

        // 修饰代码块,此时用的锁是自己创建的锁Object
        synchronized (object){
            // 关注公众号Java3y
            // doSomething
        }
    }

}

Вышеупомянутый способ (использование объекта в качестве блокировки наугад) называется в книге -->блокировка клиента,Этоне рекомендуется.

Функция, которую хочет достичь книга, заключается в следующем: добавитьputIfAbsent(), который должен быть потокобезопасным.

Предполагая, что добавление синхронизированного напрямую невозможно

Использование клиентских блокировок связывает текущую реализацию с исходным списком.:

Метод, описанный в книге, заключается в использованиикомбинацияпуть (то есть шаблон декоратора)

1.4.3 Декорирование статических методов

то, что получаетсяблокировка класса (объект файла байт-кода класса): Java3y.класс

public class Java3y {

    // 修饰静态方法代码块,静态方法属于类方法,它属于这个类,获取到的锁是属于类的锁(类的字节码文件对象)-->Java3y.class
    public synchronized void test() {

        // 关注公众号Java3y
        // doSomething
    }
}

1.4.4 Блокировки классов и блокировки объектов

Синхронизированный модифицированный статический метод получает блокировку класса (объект файла байт-кода класса), а синхронизированный модифицированный обычный метод или блок кода получает блокировку объекта.

  • Они не конфликтуют, то есть:Поток, который получает блокировку класса, и поток, который получает блокировку объекта, не конфликтуют.!

public class SynchoronizedDemo {

    //synchronized修饰非静态方法
    public synchronized void function() throws InterruptedException {
        for (int i = 0; i <3; i++) {
            Thread.sleep(1000);
            System.out.println("function running...");
        }
    }
    //synchronized修饰静态方法
    public static synchronized void staticFunction()
            throws InterruptedException {
        for (int i = 0; i < 3; i++) {
            Thread.sleep(1000);
            System.out.println("Static function running...");
        }
    }

    public static void main(String[] args) {
        final SynchoronizedDemo demo = new SynchoronizedDemo();

        // 创建线程执行静态方法
        Thread t1 = new Thread(() -> {
            try {
                staticFunction();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 创建线程执行实例方法
        Thread t2 = new Thread(() -> {
            try {
                demo.function();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 启动
        t1.start();
        t2.start();
    }
}

Результат показывает:Блокировки классов и блокировки объектов не конфликтуют!

1.5 Блокировка повторного входа

Давайте посмотрим на следующий код:


public class Widget {

	// 锁住了
	public synchronized void doSomething() {
		...
	}
}

public class LoggingWidget extends Widget {

	// 锁住了
	public synchronized void doSomething() {
		System.out.println(toString() + ": calling doSomething");
		super.doSomething();
	}
}
  1. Когда поток A входит в LoggingWidgetdoSomething()метод,На этом этапе получается блокировка объекта экземпляра LoggingWidget..
  2. Затем снова вызывается метод родительского класса Widget.doSomething()метод, этомодифицируется синхронизированным снова.
  3. Итак, теперь блокировка нашего объекта экземпляра LoggingWidget не была снята, введите блокировку виджета родительского класса.doSomething()методВсе еще нужен замок?

Не требуется!

так какДержатель замка - это "нитка", а не "призвание". Поток A уже имеет блокировку объекта экземпляра LoggingWidget и может продолжить «разблокировку», когда это снова понадобится!

Это встроенный замокповторный вход.

1.6 Когда снимать блокировку

  1. Когда метод (блок кода) будет выполнен, онБлокировка автоматического выпуска, никаких действий не требуется.
  2. Когда в коде, выполняемом потоком, возникает исключение, удерживаемая им блокировка будет автоматически снята..
  • Взаимная блокировка не произойдет из-за исключений ~

2. Заблокировать явную блокировку

2.1 Краткое введение в явную блокировку Lock

Явная блокировка блокировки доступна только после JDK 1.5. До того, как мы использовали синхронизированную блокировку для обеспечения потокобезопасности~

Явная блокировка блокировки — это интерфейс, давайте посмотрим:

Не стесняйтесь переводить его верхнюю ноту, чтобы увидеть, для чего она предназначена:

МожетКраткое содержаниенемного:

  • Метод блокировки для получения блокировкиПоддержка прерывания, тайм-аут не получен, не блокируется
  • улучшенная семантика, где заблокировать, где разблокировать надо прописать
  • Блокировка Явные блокировки могут дать нам большую гибкость, но в то же время мы должны вручную снимать блокировку.
  • Поддержка объектов условий Condition
  • Позволяет нескольким потокам чтения получать доступ к общим ресурсам одновременно

2.2 Какой из синхронизированных замков и замков Lock использовать

Как упоминалось ранее, явная блокировка Lock делает нашу программу более гибкой, а многие функции недоступны в блокировке Synchronized. Есть ли необходимость в синхронизированном замке? ?

Должно быть! ! Блокировки блокировки были лучше, чем синхронизированные блокировки во многих аспектах производительности, когда они впервые появились, но синхронизированные блокировки были оптимизированы, начиная с JDK1.6 (в конце концов, мой сын, круто)

  • Оптимизированные операции: адаптивные спин-блокировки, устранение блокировок, огрубление блокировок, облегченные блокировки, смещенные блокировки.
  • Для получения подробной информации см.:blog.CSDN.net/Колледж Чена/искусство…

Таким образом, производительность блокировки блокировки и синхронизированной блокировки фактическиразница не очень большая! Блокировка Synchronized особенно проста в использовании.Замок Lock должен заботиться о своих характеристиках, и необходимо вручную разблокировать замок.(Если вы забудете отпустить, это скрытая опасность)

Итак, мыСинхронизированные блокировки по-прежнему используются большую часть времени., используя функции, упомянутые блокировкой Lock, будет рассмотрена гибкость, обеспечиваемая использованием явной блокировки Lock~

2.3 Честный замок

Справедливые замки очень просты для понимания:

  • потоки будут следовать за нимипорядок, в котором делаются запросы на получение блокировок

Несправедливые блокировки:

  • Когда поток делает запрос, он может «прыгнуть в очередь», чтобы получить блокировку.

Блокировка и синхронизацияИспользовать несправедливую блокировку по умолчанию. Не используйте честные блокировки без необходимости

  • Справедливая блокировка приведет к некоторому потреблению производительности

Четвертый, последний

В этой статье рассказывается о синхронизированной встроенной блокировке и кратко описывается явная блокировка Lock в целом:

  • Synchronized прост в использовании, прост и имеет хорошую производительность.
  • Не используйте Lock, не используя явную функцию блокировки Lock.

Блокировка замков здесь только что представлена,Завтра объясню связанные с ним подклассы и места, на которые следует обратить внимание, так что следите за обновлениями.~

Когда я раньше изучал операционную систему, я также сделал небольшую заметку на основе книги «Компьютерная операционная система — Тан Сяодань», все из которых относительнопростое знание. Может всем поможет

Использованная литература:

Проект с открытым исходным кодом, охватывающий все точки знаний о бэкэнде Java (уже 6 тысяч звезд):GitHub.com/Zhongf UC очень…

если ты хочешьв реальном времениЕсли вы обратите внимание на мои обновленные статьи и галантерейные товары, которыми я делюсь, поищите в WeChat.Java3y.

Содержимое PDF-документоввсе вручную, если вы ничего не понимаете, вы можете напрямуюспросите меня(В официальном аккаунте есть мои контактные данные).