synchronized加锁实现方式
1、在进入加锁代码块时增加一个monitorenter指令,然后针对锁对象关联的monitor累加加锁计数器count,同时标志这个线程加了锁。synchronized是可重入锁,就是可以多次加锁,每加一次,monitor里加锁计数器都加1。
2、在离开加锁代码块是增加一个monitorexit指令,然后递减monitor里的加锁计数器,如果加锁计数器递减为0,就标志当前线程不持有锁,也就是释放了锁。
3、然后wait和notify关键字的实现也是依托于monitor实现的,有线程执行wait之后,自己会加入一个waitset中等待唤醒获取锁,notifyall操作会从monitor的waitset中唤醒所有的线程,让他们竞争获取锁。
Java对象头
synchronized用的锁是存在java对象头里的,要深入分析synchronized加锁原理就需要先了解Java对象头,Java对象头它里包含三个内容
- Mark Word :存储对象的hashCode、GC标记、锁信息等
- Class Metadata Address: 存储对象类型数据的指针
- Array Length:数组的长度(如果当前对象是数组)
1、在Mark Word里就有一个指针,是指向了这个对象实例关联的monitor的地址,这个monitor是c++实现的,不是Java实现的。这个monitor实际上是c++实现的一个ObjectMonitor对象,里面包含了一个_owner指针ÿ