上篇文章已经对多线程有个初步的认识了,这次我们来看看Java的Lock锁,主要有以下知识点:
AQS
- “
- “
在学习Lock锁之前,我们先来看看什么是AQS?
AQS
- AQS其实就是一个可以给我们实现锁的框架,juc包中很多可阻塞的类比如ReentrantLock、 ReadWriteLock都是基于AQS构建的。
- 内部实现的关键是:先进先出的队列、state状态
- 在AQS中实现了对等待队列的默认实现,子类只要重写部分的代码即可实现(大量用到了模板代码)
- AQS同时提供了互斥模式(exclusive)和共享模式(shared)两种不同的同步逻辑。一般情况下,子类只需要根据需求实现其中一种模式,当然也有同时实现两种模式的同步类,如
ReadWriteLock
。
state状态
AQS维护了一个volatile int
类型的state
变量,用来表示当前同步状态。
volatile虽然不能保证操作的原子性,但是保证了当前变量state的可见性。
compareAndSetState
compareAndSetState()是原子操作,底层其实是调用系统的CAS算法,有关CAS可移步:CAS
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
Lock
Lock是一个接口
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}
- lock()、tryLock()、tryLock(long time, TimeUnit unit)和lockInterruptibly()是用来获取锁的。
- unLock()方法是用来释放锁的。
- newCondition()方法是创建一个条件对象,用来管理那些得到锁但是不能做有用工作的线程。
ReentrantLock
ReentrantLock
,意思是”可重入锁
“,线程可以重复地获得已经持有的锁。 ReentrantLock是唯一实现了Lock接口的类。接下来我们来看看有关源码:
静态内部类
ReentrantLock实现了三个内部类,分别是Sync、NonfairSync和FairSync。
abstract static class Sync extends AbstractQueuedSynchronizer
static final class NonfairSync extends Sync
static final class FairSync extends Sync
这些内部类都是AQS的子类,这就印证了我们之前所说的:AQS是ReentrantLock的基础,AQS是构建锁的框架.
构造器
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
默认实现的是非公平锁,传入true表示使用公平锁。
lock方法
默认使用非公平锁的lock方法
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
final void lock() {
if (compareAndSetState(0, 1))//尝试获取锁
setExclusiveOwnerThread(Thread.currentThread());
else //获取失败则调用AQS的acquire方法
acquire(1);
}
参考
Java3y多线程
Java技术之AQS详解
发表回复