Графическая многопоточность Java Примечания:учебные пособия.Keane KO V.com/Java-concur…
Модель памяти Java (JMM) определяет: как и когдаdifferent threads can see
values written to shared variables by other threads,
and how to synchronize access to shared variables when necessary.
Места хранения объектов в куче и стеке Java:
Модель памяти Java и аппаратная модель:
Потоки читают данные из основной памяти в буфер процессора.Когда данные размещаются в разных местах, возникают две проблемы: видимость и статические условия.
A synchronized block in Java is synchronized on some object.
All synchronized blocks synchronized on the same object can only
have one thread executing inside them at the same time.
All other threads attempting to enter the synchronized block
are blocked
until the thread inside the synchronized block exits the block.
The synchronized keyword can be used to mark four different types of blocks:
- Instance methods -> on the instance (object) owning the method
- Статические методы -> в классе объект класса принадлежит …
- Code blocks inside instance methods
- Code blocks inside static methods
Методы синхронизированного экземпляра:
Синхронизация статических методов:
Синхронизация кодовых блоков:
При просмотре с помощью jstack только одному потоку разрешен доступ к одному и тому же объекту монитора:
Синхронизация метода экземпляра плюс синхронизация блока кода все еще для одного и того же объекта экземпляра:
Пользовательский объект монитора:
Блокировка одного и того же экземпляра объекта:
Блокировка различных объектов экземпляра:
Volatile keyword guarantees visibility of changes to variables across threads.
every read of a volatile variable will be
чтение из основной памяти компьютера,
and not from the CPU cache.every write to a volatile variable will be
written to main memory,
and not just to the CPU cache.
If Thread A writes to a volatile variable and Thread B subsequently reads the same volatile variable, then all variables visible to Thread A before writing the volatile variable, will also be visible to Thread B after it has read the volatile variable.
The reading and writing instructions of volatile variables cannot be reordered by the JVM. Instructions before and after can be reordered, but the volatile read or write cannot be mixed with these instructions. Whatever instructions follow a read or write of a volatile variable are guaranteed to happen after the read or write.
Волатильные переменные не гарантируют транзакций:
Есть еще условия гонки для volatile переменных:
Изменчивая переменная предотвращает изменение порядка:
Если не гарантируется, что переменная будет записана в основную память после обновления volatile переменной:
Чтобы гарантировать видимость, нет необходимости определять volatile для каждой переменной:
Изменчивая переменная — это барьер памяти, и инструкции до и после нее можно переупорядочить:
Пример собственного потока:
На приведенном ниже рисунке не используются собственные потоки, а на следующем рисунке используются собственные потоки:
Реализация семафора потока - занятое ожидание:
Или вы можете использовать volatile переменные:
Пример ожидания и уведомления:
Пример уведомлений и notifyAll:
Ожидающий поток может быть неожиданно разбужен, и вам нужно использовать цикл while, чтобы продолжить определение того, уведомляет ли пробужденный поток:
Разбудить все потоки сразу или по одному:
Использование строк в качестве блокировок монитора между разными потоками приведет к пробуждению других потоков:
Сигналы между разными потоками не разделяются, и ожидающий поток продолжает находиться в состоянии ожидания после пробуждения:
Примеры ожидания и пробуждения для разных потоков: