Synchronized底层实现原理总结

1. Monitor管程

Monitor

JVM中的同步是基于进入与退出监视器对象(管程对象)(Monitor)来实现的,每个对象实例都会有一个Monitor对象,Monitor对象会和Java对象一同创建并销毁。Monitor对象是由C++来实现的。

每个对象都存在着一个 monitor 与之关联,对象与其 monitor 之间的关系有存在多种实现方式,如 monitor 可以与对象一起创建销毁当线程试图获取对象锁时自动生成,但当一个 monitor 被某个线程持有后,它便处于锁定状态。

  • 如果使用 synchronized 给对象上锁(重量级)之后,该对象头的Mark Word 中就被设置指向 Monitor 对象的指针.
  • 不加 synchronized 的对象不会关联监视器

当多个线程同时访问一段同步代码时,这些线程会被放到一个EntryList集合中,处于阻塞状态的线程都会被放到该列表当中。接下来,当线程获取到对象的Monitor时,Monitor是依赖于底层操作系统的mutex lock(互斥锁)来实现互斥的,线程获取mutex成功,则会持有该mutex,这时其他线程就无法再获取到该mutex。

   如果线程调用了wait方法,那么该线程就会释放掉所持有的mutex,并且该线程会进入到WaitSet集合(等待集合)中,等待下一次被其他线程调用notify/notifyAll唤醒。如果当前线程顺利执行完毕方法,那么它也会释放掉所持有的mutex。

   通过对象互斥锁的概念来保证共享数据操作的完整性。每个对象都对应于一个可称为『互斥锁』的标记,这个标记用于保证在任何时刻,只能有一个线程访问该对象。

同步锁在这种实现方式当中,因为Monitor是依赖于底层的操作系统实现,这样就存在用户态与内核态之间的切换,所以会增加性能开销。

为什么存在用户态与内核态之间的切换?

那些处于EntryList与WaitSet中的线程均处于阻塞状态,阻塞操作是由操作系统来完成的,在linux下是通过pthread_mutex_lock函数实现的。线程被阻塞后便会进入到内核调度状态当他们获取到了锁后又会回到用户态,这会导致系统在用户态与内核态之间来回切换,严重影响锁的性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值