основное использование
- Synchronized помещается в метод экземпляра, а объект блокировки является текущим объектом this.
- Synchronized помещается в метод класса (статический метод), а объект блокировки — это объект класса в области метода.
- Синхронизированный измененный блок кода, то есть синхронизированный (объект) {}, объект блокировки - это объект в ()
synchronized
При использовании для изменения метода он передаетсяACC_SYNCHRONIZEDИдентификатор для синхронизации потоков.
synchronized
При использовании для украшения блоков кода это делается с помощьюmonitorenterиmonitorexitинструкция по завершению
Принцип реализации
-
уровень кода, Синхронизированное ключевое слово.
-
Уровень байт-кода JAVA, метод синхронизацииACC_SYNCHRONIZEDОпределение декоративного метода, использование синхронизированного блока кодаmonitorenterиmonitorexitРеализованы две инструкции.
-
Уровень JVM, Без блокировки, Блокировка смещения, Легкая блокировка, Тяжелая блокировка.
-
уровень операционной системыВызывается блокировка команды сборки cmpxchg, которая гарантирует, что следующая команда (cmpxchg) может быть выполнена только одним потоком.
-
аппаратный уровень, — это семафор, блокирующий северный мост.
1) КПМХЧГ
- Используется для сравнения и замены операндов, примитивная поддержка ЦП для CAS
- Неатомарный, впервые использованный в одноядерных процессорах.
2) префикс БЛОКИРОВКА
-
Процессор гарантирует атомарность модифицированных им инструкций.
-
Отключить изменение порядка
-
Кэш сброшен в память
Чем добиться?
1. Отметить слово в заголовке объекта
Блокировка смещения
if (锁的标记位 == 01) {
if (偏向标记是1){
是偏向锁且可偏向
boolean CAS操作结果 = CAS操作替换偏向线程的ID为当前线程
if ( CAS操作结果 == 成功){
当前线程获得锁
执行同步代码块
} else {
CAS操作失败
开始【偏向锁的撤销】{
等到全局安全点
var 状态 = 检查原来持有锁的线程的状态
if (状态 == terminated || 已经退出同步代码区)
原线程释放锁
当前线程获得锁
else if (状态 == runnable && 未退出同步代码区){
执行【偏向锁膨胀到轻量级锁】的过程{
原持有锁的线程栈幁分配锁记录、替换MarkWord并指向对象地址、执行同步代码块、CAS操作释放锁
当前线程执行轻量级锁的抢锁过程{
CAS自旋
if (自旋一定次数还没有获取锁){
膨胀到重量级锁
}
}
}
}
}
}
}else {
goto line 4 执行CAS操作
}
}else {
不是偏向锁
}
Легкий замок
if (锁的标记位 == 00) {
是轻量级锁
执行轻量级锁的抢占{
当前线程的栈幁中 分配 【锁记录】,【锁记录】由两个部分构成,【displaced Markword】 和 【onwer指针】
把锁对象的【对象头】中的【Markword】拷贝到锁记录中的【displaced Markword】中
onwer指针 指向 该锁对象
CAS修改锁对象的对象头,使其中的【指向线程锁记录的指针】 这一字段指向当前线程
if (CAS操作成功){
当前线程持有锁
}else{
CAS操作失败
CAS自旋
if (自旋超过一定次数还没有成功){
升级为重量级锁{
改变Markword
挂起当前线程
}
}
}
}
}else {
不是轻量级锁
}
2. Объект монитора монитора
В Java неявно в каждом объекте есть объект, называемый монитором (монитор объекта). Объект монитора существует в заголовке объекта Mark Word объекта Java. Исходный код этого объекта реализован на C++.
class ObjectMonitor {
...
ObjectMonitor() {
_header = NULL; //markOop object header
_count = 0;
_waiters = 0, //Number of waiting threads
_recursions = 0; //Thread reentry times
_object = NULL; //Store Monitor object
_owner = NULL; //Thread to get ObjectMonitor object
_WaitSet = NULL; //List of threads in wait state
_WaitSetLock = 0 ;
_Responsible = NULL ;
_succ = NULL ;
_cxq = NULL ; // One way list
FreeNext = NULL ;
_EntryList = NULL ; //Thread waiting for lock BLOCKED
_SpinFreq = 0 ;
_SpinClock = 0 ;
OwnerIsThread = 0 ;
_previous_owner_tid = 0; //ID of the previous owning thread of the monitor
}
...
Процесс
благодарный:Jacksgong
блокировка повторного входа
-
блокировка повторного входа в блокировку
- Просто оцените предвзятый идентификатор потока в слове метки
-
Блокировка повторного входа для облегченных замков
-
Снова поместите запись блокировки, но отображаемое ключевое слово равно нулю
-
Определяем количество повторных входов по количеству записей блокировки
-
Старший бит — это первая блокирующая запись.
-
-
Блокировка повторного входа для тяжеловесных блокировок
-
операционная система для реализации
-