1.idea查看字节码jclasslib插件装置

2.从字节码角度剖析synchronized实现

3.总结

1.idea查看字节码jclasslib插件装置
synchronize这个关键字咱们必定曾经不生疏了,接下来咱们从字节码这个角度来进行分析一下,它为什么会有加锁的成果。咱们先装置一下jclasslib插件,不便咱们查看java的字节码。

点击view --> show Bytecode With Jclasslib

就能够看到这个文件的字节码啦。

2.从字节码角度剖析synchronized实现

2.1synchronized同步代码块

public class LockByteDemo {    final Object object = new Object();    public void m1() {        synchronized (object) {            System.out.println("-------------hello sync");            //throw new RuntimeException("6");        }    }}

咱们对m1()这个ssynchronized同步代码块办法进行查看一下字节码。

咱们发现,它应用的是monitorenter指令 和 monitorexit指令 。

monitor:
其实每一个对象都有一个monitor,就是监视器,当线程获取monitor胜利的时候,这个对象就被锁住了。

monitorenter指令:
线程执行monitorenter就是为了尝试获取monitor的拥有权,过程为:

1)如果一个monitor的数值是0,那么线程间接进入monitor,并且将monitor置为1,并将对象的抢占该线程置为该线程。
2)如果该线程曾经占用monitor,则间接进入,monitor数+1 (可重入锁)
3)如果该对象的抢占线程不是该线程,那么该线程就会被阻塞,直到monitor的数值变成0,再次抢占。

monitorexit指令:

执行monitorexit的线程必须是曾经领有该对象monitor的线程,执行monitorexit命令后,monitor的进入数会减1,当减为0时,其它线程就能够尝试取得monitor的所有权。

然而这里有一个疑难,为什么只有一个monitorenter,然而有两个monitorexit?

咱们能够思考一下,这其实是和try/finally是一个情理,咱们个别编程的时候,都要在finally里加一个解锁unlock,避免异常情况的产生,那么这里也是一样的,为了避免代码出现异常,最初在进行monitorexit一下。

2.2synchronized一般同步办法

咱们会发现,一般办法标记位多了一个ACC_SYNCHRONIZED拜访标记。

当咱们调用一个办法的时候,会先查看办法的ACC_SYNCHRONIZED拜访标记是否被设置,如果设置了,线程执行会先尝试获取monitor,最初在办法实现的时候开释monitor。

2.3synchronized动态同步办法

动态同步办法的原理也是一样的,不过再多一个ACC_STATIC标记位,用来辨别是否动态同步办法。

3.总结

明天咱们分析了synchronized的字节码角度实现,其实多减少这种内功的修炼,会让我写代码的时候,有一种不一样的感觉,以前写synchronized的时候,脑子里只有单单一个synchronized关键字,当初又会联想到字节码,可能就是今人说的,从看山是山,到看山不是山的转变。