Synchronized原理分析

Monitor结构:
在这里插入图片描述

  static int i=0;
  static final Object obj = new Object();
    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (obj) {
                //临界区代码
                log.debug("获得锁");
                try {
//                    Thread.sleep(20000);
                    i++;
                    lock.wait(20000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "t1").start();

当调用Synchronized对对象加锁的时候,java代码的obj对象和操作系统提供的Monitor对象关联,obj对象中里面markword记着Monitor指针地址。Monitor对象中的owner就会记录当前线程t1,如果再有其他线程t2,t3进来的时候,先查看obj有没有Markword地址有没有关联Monitor,再查看owner有没有给其他线程占领。如果有,只能进入EntryList进行等待,t2,t3在EntryList中进入阻塞状态。
当t1执行完synchronized中,临界区所有代码,这时Monitor中的owner会空闲出来,会唤醒t2或者t3线程,假如t2给唤醒,owner对象更新为t2信息,t3继续在EntryList中阻塞。

0: getstatic
#2// <- lock引用(synchronized开始)
// 3: dup
// 4: astore_1// lock引用 -> slot 1
// 5: monitorenter// 将 lock对象 MarkWord 置为 Monitor 指针
// 6: getstatic#3// <- i
// 9: iconst_1// 准备常数 1
// 10: iadd// +1
// 11: putstatic#3// -> i
// 14: aload_1// <- lock引用
// 15: monitorexit// 将 lock对象 MarkWord 重置, 唤醒 EntryList
// 16: goto2419: astore_2// e -> slot 2
// 20: aload_1// <- lock引用21: monitorexit// 将 lock对象 MarkWord 重置, 唤醒 EntryList
// 22: aload_2// <- slot 2 (e)
// 23: athrow// throw e
// 24: return

字节码中,从monitorenter 进入锁方法,monitorexit释放锁,即使发生异常也会monitorexit。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值