网站开发分类,预约网站制作,网页设计叫什么岗位,wordpress 运行效率文章目录 1 概要2 相关文章3 例子4 方法详解4.1 lock()4.2 unlock()4.3 tryLock()4.4 其他公平锁 总结 1 概要
ReentrantLock 通过实现Lock接口的行为#xff0c;提供锁机制。但是实现委托给了内部的Sync#xff0c;Sync extends AbstractQueuedSynchronizer#xff0c;继承… 文章目录 1 概要2 相关文章3 例子4 方法详解4.1 lock()4.2 unlock()4.3 tryLock()4.4 其他公平锁 总结 1 概要
ReentrantLock 通过实现Lock接口的行为提供锁机制。但是实现委托给了内部的SyncSync extends AbstractQueuedSynchronizer继承了AQS的能力。此时还提供两个具体的实现公平锁和非公平锁。首先如果对AQS不了解请看java并发编程 AbstractQueuedSynchronizer(AQS)详解一。下文会对上述几个点进行详解内部原理
2 相关文章
java并发编程 AbstractQueuedSynchronizer(AQS)详解一java并发编程 AbstractQueuedSynchronizer(AQS)详解二
3 例子
ReentrantLock 注释上的例子。。。。 如果lock没有被阻塞住就代表获取到锁然后执行业务逻辑。最终finally 里释放锁防止抛异常
public class X {private final ReentrantLock lock new ReentrantLock(); // ... public void m() { lock.lock();// block until condition holds try { // ... method body } finally { lock.unlock() ; } }
}4 方法详解
先看非公平锁实现。 先说下在ReentrantLock里上锁是通过state变量如果是0且从0原子变成1成功代表获取成功如果重入则state 1,释放锁就减1,0的时候释放锁。
4.1 lock()
public void lock() {//委托给sync执行sync.lock();
}
//非公平锁实现
final void lock() {//先自己尝试设置成1 如果成功设置拥有锁的线程为自己if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());else//aqs 的acquire 若对aqs不熟悉的请先看相关文章//他会进入tryAcquire(arg)的具体实现acquire(1);
}
protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);
}
//非公平的尝试加锁
final boolean nonfairTryAcquire(int acquires) {final Thread current Thread.currentThread();int c getState();if (c 0) {//如果是0 尝试变成1此时如果阻塞队列中有阻塞的线程但是新的加锁线程还是有可能获取到锁的//因为释放锁后只会从Head.next的Node去唤醒获取锁, 你后来的线程比先来的先拿到锁公平吗 非公平锁if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}//可重入的实现。如果当前线程是自己也就是lock拿到锁再lock直接state 1, 因为独占锁所以不需要原子性1else if (current getExclusiveOwnerThread()) {int nextc c acquires;if (nextc 0) // overflowthrow new Error(Maximum lock count exceeded);setState(nextc);return true;}//现在state不是0且持有锁的线程不是自己尝试加锁失败return false;
}4.2 unlock()
持有锁的线程释放锁
public void unlock() {sync.release(1);
}public final boolean release(int arg) {// aqs的抽象实现if (tryRelease(arg)) {//成功了会唤醒head.next线程Node h head;if (h ! null h.waitStatus ! 0)unparkSuccessor(h);return true;}//释放失败 可重入的时候从5 - 4return false;
}
protected final boolean tryRelease(int releases) {//不需要原子性操作是因为当前持有锁int c getState() - releases;if (Thread.currentThread() ! getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free false;//state 0 的时候代表释放锁if (c 0) {free true;setExclusiveOwnerThread(null);}setState(c);return free;
}4.3 tryLock()
对比lock 其实就没有进入阻塞队列的逻辑。比较简单
public boolean tryLock() {return sync.nonfairTryAcquire(1);
}4.4 其他
其他方法都可类比lock 和 unlock。如阻塞一段时间的等。
公平锁
公平锁核心方法实现对比下和非公平锁的区别就可以看到多了!hasQueuedPredecessors() 这个方法。很清晰。
protected final boolean tryAcquire(int acquires) {final Thread current Thread.currentThread();int c getState();if (c 0) {//区别在这如果阻塞队列有阻塞的线程就不去争抢会return falseif (!hasQueuedPredecessors() compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current getExclusiveOwnerThread()) {int nextc c acquires;if (nextc 0)throw new Error(Maximum lock count exceeded);setState(nextc);return true;}return false;
}
//阻塞队列中没有阻塞的线程
public final boolean hasQueuedPredecessors() {Node t tail;Node h head;Node s;return h ! t ((s h.next) null || s.thread ! Thread.currentThread());
}总结
ReentrantLock 本质上是基于AQS实现的可重入锁且提供了公平和非公平的机制逻辑较为简单需要对AQS熟练掌握。