LockSupport
与wait()的区别:
wait需要让已经获取锁的线程释放锁并阻塞,而LockSupport不需要
wait指定唤醒某个线程更麻烦,而LockSupport更便捷
notify(notify不释放锁)不可调用在wait之前,而unpark可以调用在park之前
// 让当前线程阻塞
LockSupport.park();
// 唤醒某个线程
LockSupport.unpark(t);
LockSupport.part()是基于Unsafe.part()实现的(Unsafe提供了硬件级别的原子操作)
AQS
- AQS使用了模板设计模式
- AQS的核心是state,state使用volatile保持可见性
- AQS内部存在一个阻塞队列(双向链表),每当获取锁时都会从该队列中进行非公平夺取
部分源码解读(ReentrantLock)
先看一下泳道图(其中不包括线程队列)
@ReservedStackAccess
final boolean nonfairTryAcquire(int acquires) {
Thread current = Thread.currentThread();
// 获取state
int c = this.getState();
if (c == 0) { // 如果state等于0,则用CAS获取一个线程
if (this.compareAndSetState(0, acquires)) {
// 将当前线程设置为独占线程
this.setExclusiveOwnerThread(current);
return true;
}
} else if (current == this.getExclusiveOwnerThread()) { //如果当前线程等于独占线程
// state增加(体现了可重入锁的设计)
int nextc = c + acquires;
if (nextc < 0) {
throw new Error("Maximum lock count exceeded");
}
this.setState(nextc);
return true;
}
return false;
}