synchronized底层如何实现 锁优化 怎么优化?【面试题详解】

今天爱分享给大家带来synchronized底层如何实现 锁优化 怎么优化?【面试题详解】,希望能够帮助到大家。

synchronized 是 Java 内建的同步机制,所以也有人称其为 Intrinsic Locking,它提供了互斥的语义和可见性,当一个线程已经获取当前锁时,其他试图获取的线程只能等待或者阻塞在那里。

原理:
synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性

底层实现:
1)同步代码块是使用monitorenter和monitorexit指令实现的, ,当且一个monitor被持有之后,他将处于锁定状态。线程执行到monitorenter指令时,将会尝试获取对象所对应的monitor所有权,即尝试获取对象的锁;
2)同步方法(在这看不出来需要看JVM底层实现)依靠的是方法修饰符上的ACC_SYNCHRONIZED实现。 synchronized方法是在Class文件的方法表中将该方法的access_flags字段中的synchronized标志位置1,表示该方法是同步方法并使用调用该方法的对象或该方法所属的Class在JVM的内部对象表示 Klass 做为锁对象。

Java对象头和monitor是实现synchronized的基础!
synchronized存放的位置:
synchronized用的锁是存在Java对象头里的。
其中, Java对象头包括:
Mark Word(标记字段): 用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等等。它是实现轻量级锁和偏向锁的关键
Klass Pointer(类型指针): 是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
monitor: 可以把它理解为一个同步工具, 它通常被描述为一个对象。 是线程私有的数据结构。

锁优化,怎么优化?
jdk1.6对锁的实现引入了大量的优化。 锁主要存在四中状态,依次是:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态,他们会随着竞争的激烈而逐渐升级。 注意锁可以升级不可降级,这种策略是为了提高获得锁和释放锁的效率。 重量级锁降级发生于STW阶段,降级对象为仅仅能被VMThread访问而没有其他JavaThread访问的对象。( HotSpot JVM/JRockit JVM是支持锁降级的)
偏斜锁:
当没有竞争出现时,默认会使用偏斜锁。JVM 会利用 CAS 操作(compare and swap),在对象头上的 Mark Word 部分设置线程 ID,以表示这个对象偏向于当前线程,所以并不涉及真正的互斥锁。
自旋锁:
自旋锁 for(;;)结合cas确保线程获取取锁
就是让该线程等待一段时间,不会被立即挂起,看持有锁的线程是否会很快释放锁。怎么等待呢?执行一段无意义的循环即可(自旋)。
轻量级锁:
引入偏向锁主要目的是:为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径。 当关闭偏向锁功能或者多个线程竞争偏向锁导致偏向锁升级为轻量级锁,则会尝试获取轻量级锁
重量级锁:
重量级锁通过对象内部的监视器(monitor)实现,其中monitor的本质是依赖于底层操作系统的Mutex Lock实现,操作系统实现线程之间的切换需要从用户态到内核态的切换,切换成本非常高。

人已赞赏
Java

Thread和Runnable的关系与区别【面试题详解】

2020-11-6 13:47:26

Java

synchronized底层如何实现 锁优化 怎么优化?【面试题详解】

2020-11-6 14:09:37

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
'); })();