synchronized的实现原理?
我们使用synchronized的时候,发现不用自己去lock和unlock,是因为JVM帮我们把这个事情做了。
- synchronized修饰代码块时,JVM采用monitorenter、monitorexit两个指令来实现同步,monitorenter 指令指向同步代码块的开始位置, monitorexit 指令则指向同步代码块的结束位置。
/**
* @author 百里
*/
public class BaiLiSyncDemo {
public void main(string[] args) {
synchronized (this) {
int a = 1;
}
}
}
public void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=2, locals=5, args_size=2
0: aload_0
1: dup
2: astore_2
3: monitorenter
4: iconst_1
5: istore_3
6: aload_2
7: monitorexit
8: goto 18
11: astore 4
13: aload_2
14: monitorexit
15: aload 4
17: athrow
18: return
- synchronized修饰同步方法时,JVM采用ACC_SYNCHRONIZED标记符来实现同步,这个标识指明了该方法是一个同步方法。同样可以写段代码反编译看一下。
/**
* @author 百里
*/
public class BaiLiSyncDemo {
public synchronized void main(String[] args) {
int a = 1;
}
}
synchronized锁住的是什么呢?
实例对象结构里有对象头,对象头里面有一块结构叫Mark Word,Mark Word指针指向了monitor。
所谓的Monitor其实是一种同步机制,我们可以称为内部锁或者Monitor锁。
monitorenter、monitorexit或者ACC_SYNCHRONIZED都是基于Monitor实现的。
反编译class文件方法:
反编译一段synchronized修饰代码块代码,javap -c -s -v -l ***.class,可以看到相应的字节码指令。
![](/images/780-200-2.jpg)