以非公平锁为例
- ReentrantLock的lock调用了其内部类(AQS)的lock方法
public void lock() {
sync.lock();
}
- 看非公平锁实现此接口
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
/**
* Performs {@link Lock#lock}. The main reason for subclassing
* is to allow fast path for nonfair version.
*/
abstract void lock();
***省略**
}
- 如果是第一次就让state原子性加1,并把当前线程设置为owner线程,表示第一次来竞争成功,否则调用acquire方法
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() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
}
- acquire逻辑还会尝试竞争锁,失败会将线程加入队列,尝试竞争资源逻辑是tryAcquire
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
- 这个是AQS的定义的默认方法,现在就要看ReetrantLock中内部类重写次方法的逻辑
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
- 当我们进入此逻辑时,还会去判断state是否为0,如果为0,就表示首次获得锁(因为进入此逻辑时,原来占有的资源的线程可能会释放),进行的逻辑和之前的逻辑相同。如果已经获得锁,看当前线程是否等于owner线程,表示发生了锁重入,发生锁重入,将state++,返回true。
-
tryRelease
,当进入此方法时,判断当前线程是否等于getExclusiveOwnerThread的线程,如果相同,则会让state–,让后false,并不会去唤醒其他线程,因为重入状态并不会真正是否锁,当检测到state为0时,才会去setExclusiveOwnerThread(null),返回true。
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {//首次获得锁
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
// 已经获得锁,看当前线程是否等于owner线程,表示发生了锁重入
else if (current == getExclusiveOwnerThread()) {
//state++
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
//state--
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
//只是-1并没有释放锁
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
版权声明:本文为m0_60181979原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。