面试中如何回答Java中的锁机制

Java中锁机制

Java中多线程加锁机制主要有两种,一种是JDK实现的lock,另外一种是JVM底层实现的Synchronized关键字。

Synchronized是JVM底层实现的,JVM原生支持synchronized,而reentrantlock是JDK实现的,并不是所有jdk版本都支持reentrantlock,而且使用synchronized无需显式地释放锁,JVM自己会保证锁的释放。

在JDK1.6后,对synchronized进行了很多优化,如偏向锁、轻量级锁等,synchronized的性能已经与Reentrantlock大致相同,除非要使用Reentrantlock的一些高级功能(实现公平锁、中断锁等),一般推荐使用synchronized关键字来实现加锁机制。

synchronized锁机制原理实现

每个对象都有一个监视器锁(monitor),一个监视器锁只能同时最多被一个线程拥有。如果一个线程想要进入某个同步代码块,需要执行monitorenter字节码指令尝试去获取该对象的监视器锁的所有权,执行完同步代码,需要执行monitorenter字节码指令去释放该对象的监视器锁的所有权。这种获取监视器锁的操作是比较重量级的,因为监视器锁本质是依赖于底层操作系统的mutex lock来实现的,需要耗费较长时间。

因此,在JDK1.6,引入了偏向锁和轻量级锁对synchronized进行优化。一个线程尝试去获取一个对象的偏向锁,会使用cas操作将这个对象的对象头中mark work修改为当前线程的ID,如果修改成功表示成功获取该对象的偏向锁,否则获取失败。

当两个线程交替获取一个对象的锁时,偏向锁会升级为轻量级锁,首先先在线程的栈帧中会建立一块锁记录(lock record),将对象头中mark word拷贝到锁记录中,然后将mark word更新为指向锁记录的指针,并将锁记录中的owner指针指向锁对象的mark word。如果更新成功,说明成功获取该对象的轻量级锁,否则获取失败,两个线程发生竞争,进入重量级锁的争夺,也就是monitor锁的竞争。

猜你喜欢

转载自blog.csdn.net/tubro2017/article/details/89246749
今日推荐