前言
除了synchronized加锁之外,还有lock锁的方式,这俩种锁有什么区别尼?
synchronized
synchronized锁是非公平的锁,是独占的锁,属于抢占式的锁,而且根据synchronized在类中修饰的位置不同,锁的定义也不一样
lock
可以是公平锁也可以是非公平锁,默认实现是非公平的锁,他的实现方式与synchronized也不同,lock是一种可中断锁,使用lockSupport来做线程的中断,
lock实现方式
猜想:
- 锁的互斥性,当一个线程在使用时,其他线程是无法使用的,需要一个status 来记录当前线程是否拥有锁,0(无锁), 1(有锁),
- 没有抢占到锁的线程?-> 释放cpu资源,等待--->唤醒
- 等待的线程如何存储?->使用那种数据结构来处理(能否插队)
- 公平和非公平
- 重入的特性(识别是否是同一个线程)
实现技术方案
- volatile state (0无锁 ,1有锁,-1代表重入)
- wait/notify |condition 唤醒线程? LockSupport.park /unpark
- 双向链表存储等待线程
- 逻辑层面实现公平与非公平
- 早某一个地方存储当前获得锁线程的ID,判断下次抢占锁的线程是否是同一个。
lock的实现源码分析
public interface Lock {
void lock();
}
lock的子类ReentrantLock类的构造函数,根据传值对于公平和非公平锁实现做了定义
public ReentrantLock() {
sync = new NonfairSync();
}
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
NonfairSync(非公平锁)
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
/**
* 比较并设置值 CAS,这里调用的是AQS中的unsafe.compareAndSwapInt(this, stateOffset, expect, update);
* unsafe是个native调用的是机器内存值,这里的核心意思是,取用stateOffset当前的值,传入的值是0和1,拿
* 0和stateOffset的值做比较,期望的值是0,然后将stateOffset的值更新成1,这里主要java底层借助计算机内存地址
* 来做的,如何比较的期望值得到了,独占所标记住
*
*/
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
//尝试获取锁,进入等待序列
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
//获取AQS中volatile 的state值,再次使用CAS来获取锁,如果成功则标记
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {//当前线程是否为state=0的线程,将state标记改为1
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
addWaiter(Node node)
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
// Try the fast path of enq; backup to full enq on failure
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
enq(node);
return node;
}