Synchronized和Reentrantlock的区别

1. Reentrantlock的使用

1. 初始化选择公平锁还是非公平锁
Reentrantlock lock = new Reentrantlock(true);
2. 可用于代码块
lock.lock();
try{

}finally{
	3. 释放锁
	lock.unlock();
}
return ResponseUtil.success();

2. Reentrantlock的原理

Reentrantlock有两种使用模式,一种是公平锁,一种是非公平锁,通过在创建实例的时候传参设置。

1. 设置公平模式
Reentrantlock lock = new Reentrantlock(true);
2. 设置非公平模式
Reentrantlock lock = new Reentrantlock();
// 公平模式下Reentrantlock的构造函数源码
public ReentrantLock() {
    this.sync = new ReentrantLock.NonfairSync();
}
// 非公平模式下Reentrantlock的构造函数源码
public ReentrantLock(boolean fair) {
    this.sync = (ReentrantLock.Sync)(fair ? new ReentrantLock.FairSync() : new ReentrantLock.NonfairSync());
}

其中涉及到几个类:FairSync、NonfairSync,这两个类是Reentrantlock中的内部类,Reentrantlock的结构图如下。从结构图可以看出,Reentrantlock的主要实现都交给AQS(AbstractQueuedSynchronizer类)去实现。
image

2.1 Reentrantlock的lock方法在AQS中的实现

1. lock --> acquire
public void lock() {
	this.sync.acquire(1);
}

2. acquire --> tryAcquire
public final void acquire(int arg) {
	if (!this.tryAcquire(arg) && this.acquireQueued(this.addWaiter(AbstractQueuedSynchronizer.Node.EXCLUSIVE), arg)) {
		selfInterrupt();
	}
}
3. tryAcquire在FairSync中的实现

image

4. tryAcquire在NonfairSync中的实现

image

2.2 公平模式和非公平模式下上锁流程的简单理解

公平模式
image

非公平模式
image

AQS使用state同步状态,0表示未上锁,1表示上锁。如果当前线程无法抢占到锁资源,AQS会将其放入到双向队列中阻塞。

3. Synchronized和Reentrantlock的区别

1. 核心区别:
	Synchronized适合于并发竞争低的情况,原因是Synchronized当遇到竞争激励的并发情况时,锁会升级成重量级锁,而一旦升级完成后,锁不会完成降级。
	Reentrantlock适合于动态高并发的情况,原因是Reentrantlock通过在高并发下线程的挂起,来减少竞争,提高并发能力。

2. Synchronized是关键字,是jvm层面实现的;Reentrantlock是java api实现的。

3. Synchronized是隐式锁,会自动释放;Reentrantlock是显式锁,需要手动调用unlock释放锁资源。

4. Synchronized不能响应中断;Reentrantlock可以。
posted @ 2022-05-11 10:00  SmartLiu  阅读(356)  评论(0编辑  收藏  举报