synchronize总结

官方解释,别人翻译的:

同步方法的运行是隐式的,类似于jvm对于方法的引用和返回的支持。同步方法通过在运行常量池里method_info数据结构中的ACC_SYNCHRONIZED标签来标注。
如果一个线程发现调用的方法有ACC_SYNCHRONIZED标记,那么线程的执行过程就变成:获取monitor对象,调用方法,释放monitor对象。
在某个线程持有monitor对象时,如果其他线程也想获取该对象,则会别阻塞。
如果一个同步方法执行过程中发生异常,而且方法自己没有处理,那么在异常被向外抛时,线程也会自动释放monitor对象。

1.使用方式

a.普通方法,上锁的对象是类实例,反编译后字节码中会有ACC_SYNCHRONIZED关键字

b .静态方法,上锁的对象是类对象,和上面差不多

c.静态代码块,自定义锁的对象,在代码块的前后会有monitorenter、monitorexit关键字,标识计数器+1,或者减1

2.存放方式

synchronized使用的锁对象是存储在Java对象头里的,而对象头结构

其中Mark Word在默认情况下存储着对象的HashCode、分代年龄、锁标记位等以下是32位JVM的Mark Word默认存储结构:

还有如下可能变化的结构:

Synchronized属于结构中的重量级锁,对象的对象头的锁信息里面包含了monitor,每个对象都有一个monitor与之关联,类似一个管家,获取锁本质就是获取monitor

monitor是由ObjectMonitor(c++)实现的,

结构中几个重要的字段要关注,_count、_owner、_EntryList、_WaitSet。

count用来记录线程进入加锁代码的次数。

owner记录当前持有锁的线程,即持有ObjectMonitor对象的线程。

EntryList是想要持有锁的线程的集合。

WaitSet 是加锁对象调用wait()方法后,等待被唤醒的线程的集合。

3.锁的获取逻辑

4.锁升级

 5.synchronize原理

6.synchronize和lock 

参考:

https://blog.csdn.net/a760352276/article/details/107620307

https://www.cnblogs.com/little-sheep/p/9909111.html  这是厉害

原文地址:https://www.cnblogs.com/longsanshi/p/14286231.html