面试刷题15synchronized底层是如何实现的?

编程

<br />所有的同步场景都是基于锁。锁在并发编程中发挥重要作用。<br />

<br />我是李福春,我在准备面试,今天的题目是:<br />

<br />

<br />

synchronized底层是如何实现的?

答: synchronized是在底层的jvm中实现的,即c++写的,synchronized的实现是基于一对monitorenter, monitorexit指令实现的,monitor对象是同步的基本实现单元。<br />

<br />在java6中,monitor依靠操作系统提供的内部互斥锁,需要在用户态空间和内核态空间切换,所以同步操作是一个比较重的操作,开销比较大。<br />

<br />在java7之后,monitor有三种不同的实现,即偏斜锁,轻量级锁,重量级锁。<br />

<br />基于对象头的markword,标记上偏向的线程id, 在没有竞争的条件下,使用的是偏斜锁;<br />当有多个线程来竞争偏斜锁,基于cas对对象头的markword来进行竞争,如果拿到了,升级为轻量级锁。<br />没拿到则升级为重量级锁;<br />

<br />锁降级发生在jvm进入安全点检查的时候,对monitor进行降级。<br />

<br />

synchronized底层实现

<br />对象头结构:<br />

<br />

<br />

<br />sharedRuntime.cpp 解释器和编译器的运行时基类。

```cpp

Handle h_obj(THREAD, obj);

if (UseBiasedLocking) {

// Retry fast entry if bias is revoked to avoid unnecessary inflation

ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);

} else {

ObjectSynchronizer::slow_enter(h_obj, lock, CHECK);

}

<br />

<br />偏斜锁逻辑代码:<br />

```cpp

void ObjectSynchronizer::fast_enter(Handle obj, BasicLock* lock,

bool attempt_rebias, TRAPS) {

if (UseBiasedLocking) {

if (!SafepointSynchronize::is_at_safepoint()) {

BiasedLocking::Condition cond = BiasedLocking::revoke_and_rebias(obj, attempt_rebias, THREAD);

if (cond == BiasedLocking::BIAS_REVOKED_AND_REBIASED) {

return;

}

} else {

assert(!attempt_rebias, "can not rebias toward VM thread");

BiasedLocking::revoke_at_safepoint(obj);

}

assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");

}

slow_enter(obj, lock, THREAD);

}

<br />

<br />轻量级锁:

```cpp

void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) {

markOop mark = obj->mark();

if (mark->is_neutral()) {

// 将目前的Mark Word复制到Displaced Header上

lock->set_displaced_header(mark);

// 利用CAS设置对象的Mark Word

if (mark == obj()->cas_set_mark((markOop) lock, mark)) {

TEVENT(slow_enter: release stacklock);

return;

}

// 检查存在竞争

} else if (mark->has_locker() &&

THREAD->is_lock_owned((address)mark->locker())) {

// 清除

lock->set_displaced_header(NULL);

return;

}

// 重置Displaced Header

lock->set_displaced_header(markOopDesc::unused_mark());

ObjectSynchronizer::inflate(THREAD,

obj(),

inflate_cause_monitor_enter)->enter(THREAD);

}

<br />

<br />

<br />

# java体系中的锁

<br />

<br />

<br />java提供的锁有哪些<br />

<br />

![image.png](https://oscimg.oschina.net/oscnet/up-6852ef51cdfe1d398b7dc641595a7ef425c.png)

<br />

<br />

<br />

<br />再入读写锁:<br />

<br />

```java

public class RWSample {

private final Map<String, String> m = new TreeMap<>();

private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

private final Lock r = rwl.readLock();

private final Lock w = rwl.writeLock();

public String get(String key) {

r.lock();

System.out.println("读锁锁定!");

try {

return m.get(key);

} finally {

r.unlock();

}

}

public String put(String key, String entry) {

w.lock();

System.out.println("写锁锁定!");

try {

return m.put(key, entry);

} finally {

w.unlock();

}

}

// …

}

<br />优化的读写锁:StampedLock<br />代码如下:<br />读取之前先通过validate方法判断是否进入写状态,如果没有进入写状态,不用加读锁,避免了开销;<br />否则增加读锁,保证一致性。<br />

public class StampedSample {

private final StampedLock sl = new StampedLock();

void mutate() {

long stamp = sl.writeLock();

try {

write();

} finally {

sl.unlockWrite(stamp);

}

}

Data access() {

long stamp = sl.tryOptimisticRead();

Data data = read();

if (!sl.validate(stamp)) {

stamp = sl.readLock();

try {

data = read();

} finally {

sl.unlockRead(stamp);

}

}

return data;

}

// …

}

<br />

小结

<br />本篇先介绍了synchronized的底层实现原理,介绍了java8中引入的3种级别的锁,以及锁升级和降级过程。<br />

<br />然后介绍了java体系中的其它的锁和优化读写锁使用场景。<br />

<br />

<br />

<br />

<br />

原创不易,转载请注明出处。

以上是 面试刷题15synchronized底层是如何实现的? 的全部内容, 来源链接: utcz.com/z/514802.html

回到顶部