Synchronized三部曲:What、How、Why

首先声明,这个是转贴,转自:https://juejin.im/post/5d5374076fb9a06ac76da894?utm_source=gold_browser_extension,下面是我看过之后自己的总结。

一、What

Synchronized是什么?

Synchronized是JAVA语言中的关键字,他可以用在方法上例如:

也可以用在代码块上,例如:

他的作用是锁,什么意思呢?就是在并发环境下,有且只有一个线程可以进入被Synchronized包裹的地方,保证线程安全。

二、How

Synchronized是怎么实现的呢?

经过反编译发现,添加了synchronized关键字的代码块,多了两个指令monitorenter、monitorexit。即JVM使用monitorenter和monitorexit两个指令实现同步。

添加了synchronized关键字的方法,多了ACC_SYNCHRONIZED标记。即JVM通过在方法访问标识符(flags)中加入ACC_SYNCHRONIZED来实现同步功能。

那么 monitorenter、monitorexit、ACC_SYNCHRONIZED 又是怎么实现锁的呢?

Monitorenter  执行流程

monitorexit 执行流程

ACC_SYNCHRONIZED 是隐式的,也是通过moitor 执行流程

monitor 是一个虚拟机中的对象,他内部有2个列表,_EntryList 和 _WaitSet 

举个例子

 synchronized(this){  //进入_EntryList队列
            doSth();
            this.wait();  //进入_WaitSet队列
        }
  • 想要获取monitor的线程,首先会进入_EntryList队列。
  • 当某个线程获取到对象的monitor后,进入_Owner区域,设置为当前线程,同时计数器_count加1。
  • 如果线程调用了wait()方法,则会进入_WaitSet队列。它会释放monitor锁,即将_owner赋值为null,_count自减1,进入_WaitSet队列阻塞等待。
  • 如果其他线程调用 notify() / notifyAll() ,会唤醒_WaitSet中的某个线程,该线程再次尝试获取monitor锁,成功即进入_Owner区域。
  • 同步方法执行完毕了,线程退出临界区,会将monitor的owner设为null,并释放监视锁。

三.Why

为什么这么设计呢,这样设计其实是很大程度上的解耦,每次需要上锁的时候,根据对象头(存到内存中的对象都有对象头)获取monitor对象,然后进行管理就好了,如果是每个对象都有一个是否上锁的标志的话,就会又乱又麻烦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值