synchronized

synchronized的原理
  • Java对象头。java对象头中主要包括两部分数据,Mark Word(标记字段,用处存储对象自身的运行时数据,比如哈希码、GC分代年龄、锁状态标志ACC_SYNCHRONIZED、偏向线程ID等)和Klass Pointer(类型指针)。其中Klass Point是对象指向它的类元数据的指针,虚拟机通过这个指针来确定对象是哪个类的实例。Mark Word用于存储对象自身的运行时数据,它是实现轻量级锁和偏向锁的关键。

  • monitor:就像一个黑盒子,一次只能有一个资源(对象或同步代码块)进入。当资源被释放,monitor的占用字段就被置为0,也就是出箱,此时会根据线程优先级等规则,选出下一个同步资源进入监视器,monitor的占用字段置为1。监视器锁(monitor)是依赖于底层的操作系统的 Mutex Lock 来实现的,Java 的线程是映射到操作系统的原生线程之上的。

​ jdk1.6对synchronized进行了各种优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。如:偏向锁通过对比Mark Word解决加锁问题,避免执行CAS操作。而轻量级锁是通过用CAS操作和自旋来解决加锁问题,避免线程阻塞和唤醒而影响性能。重量级锁是将除了拥有锁的线程以外的线程都阻塞。

​ synchronized 同步语句块的实现使用的是 monitorenter 和 monitorexit 指令,其中 monitorenter 指令指向同步代码块的开始位置,monitorexit 指令则指明同步代码块的结束位置。

  • synchronized 加在静态方法上锁的是Class,叫类锁,加在非静态方法上叫对象锁;synchronized(this)和synchronized()锁的都是this对象,synchronized(obj)锁的是obj对象。
posted @ 2021-04-22 10:53  i%2  阅读(43)  评论(0)    收藏  举报