ReentrantLock的实现依赖于java的同步器框架AbstractQueuedSynchronizer(AQS);
AQS使用一个整型的volatile变量(命名为state)来维护同步状态。

1、类图

ReentrantLock.pngSync.png

2、example

  1. public class ReentrantLockExample {
  2. int a = 0;
  3. ReentrantLock lock = new ReentrantLock(true);
  4. public void writer() {
  5. lock.lock(); //加锁
  6. try {
  7. a++;
  8. } finally {
  9. lock.unlock(); //解锁
  10. }
  11. }
  12. public void reader() {
  13. lock.lock(); //加锁
  14. try {
  15. int i = a;
  16. } finally {
  17. lock.unlock(); //解锁
  18. }
  19. }
  20. }

3、公平锁

加锁

加锁方法lock()调用轨迹如下:

  1. ReentrantLock :lock()。
  2. FairSync :lock()。
  3. AbstractQueuedSynchronizer :acquire(int arg)。
  4. ReentrantLock : tryAcquire(int acquires)。

    1. protected final boolean tryAcquire(int acquires) {
    2. final Thread current = Thread.currentThread();
    3. int c = getState(); //读volatile变量 state
    4. if (c == 0) {
    5. if (!hasQueuedPredecessors() &&
    6. compareAndSetState(0, acquires)) { //cas更新
    7. setExclusiveOwnerThread(current); //设置互斥锁拥有线程
    8. return true;
    9. }
    10. }
    11. else if (current == getExclusiveOwnerThread()) { //重入
    12. int nextc = c + acquires;
    13. if (nextc < 0)
    14. throw new Error("Maximum lock count exceeded");
    15. setState(nextc); //写 volatile变量 sate
    16. return true;
    17. }
    18. return false;
    19. }

    解锁

    解锁方法unlock()调用轨迹如下:

  5. ReentrantLock :unlock()。

  6. AbstractQueuedSynchronizer : release(int arg)。
  7. Sync : tryRelease(int release)。
    1. protected final boolean tryRelease(int releases) {
    2. int c = getState() - releases; //读volatile变量
    3. if (Thread.currentThread() != getExclusiveOwnerThread())
    4. throw new IllegalMonitorStateException();
    5. boolean free = false;
    6. if (c == 0) {
    7. free = true;
    8. setExclusiveOwnerThread(null); //设置互斥锁持有线程为null
    9. }
    10. setState(c); //写volatile变量
    11. return free;
    12. }

    4、非公平锁

    加锁

    解锁