并发编程--线程同步之 synchronized关键字(二)

上篇文章对synchronized有了一个简单的理解并发编程–线程同步之 synchronized关键字(一)
本篇主要重点了解一下编译后的过程是如何的?

synchronized是基于JVM内置锁实现,通过内部对象Monitor(监视器锁)实现。
synchronized关键字被编译成字节码后会被翻译成monitorenter和monitorexit两条指令分别在同步块逻辑代码的起始位置与结束位置。
并发编程--线程同步之 synchronized关键字(二)_第1张图片
每个同步对象都有一个自己的Monitor(监视器锁),加锁过程如下图所示:
并发编程--线程同步之 synchronized关键字(二)_第2张图片

Monitor监视器锁

任何一个对象都有一个Monitor与之关联,当且一个Monitor被持有后,它将处于锁定状态。Synchronized在JVM里的实现都是 基于进入和退出Monitor对象来实现方法同步和代码块同步,虽然具体实现细节不一样,但是都可以通过成对的MonitorEnter和MonitorExit指令来实现。

  • monitorenter
    每个对象都是一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权。
    如上图,有三种情况:
    1、若monitor进入数为0,进入数+1,该线程即为monitor所有者;
    2、若线程已经占有该monitor,则重新进入,进入数再+1;
    3、若其他线程占用,则阻塞,知道进入数为0,重新获取所有权;
  • monitorexit
    注:执行monitorexit必须是object所对应的monitor所有者

什么是monitor?

可以把它理解为 一个同步工具,也可以描述为 一种同步机制,它通常被 描述为一个对象。与一切皆对象一样,所有的Java对象是天生的Monitor,每一个Java对象都有成为Monitor的潜质,因为在Java的设计中 ,每一个Java对象自打娘胎里出来就带了一把看不见的锁,它叫做内部锁或者Monitor锁。也就是通常说Synchronized的对象锁,MarkWord锁标识位为10,其中指针指向的是Monitor对象的起始地址。在Java虚拟机(HotSpot)中,Monitor是由ObjectMonitor实现的,其主要数据结构如下(位于HotSpot虚拟机源码ObjectMonitor.hpp文件,C++实现的):

ObjectMonitor

有两个队列:

  • _EntryList
  • _WaitSet

用来保存ObjectWaiter对象列表( 每个等待锁的线程都会被封装成ObjectWaiter对象 ),_owner指向持有ObjectMonitor对象的线程,当多个线程同时访问一段同步代码时:

  1. 首先进入_EntryList,
  2. 若线程调用 wait() 方法
  3. 若当前线程执行完毕

你可能感兴趣的:(分布式,并发编程,java,synchronized原理)