目前是下图的样子,线程1,2写锁都已经释放了,线程3加上读锁后还未释放,此时线程4来尝试加锁
    image.png
    仍然走的下面的代码
    读锁加锁成功,下一个线程来加读锁 - 图2
    tryAcquireShared,尝试加锁。

    1. protected final int tryAcquireShared(int unused) {
    2. /*
    3. * Walkthrough:
    4. * 1. If write lock held by another thread, fail.
    5. * 2. Otherwise, this thread is eligible for
    6. * lock wrt state, so ask if it should block
    7. * because of queue policy. If not, try
    8. * to grant by CASing state and updating count.
    9. * Note that step does not check for reentrant
    10. * acquires, which is postponed to full version
    11. * to avoid having to check hold count in
    12. * the more typical non-reentrant case.
    13. * 3. If step 2 fails either because thread
    14. * apparently not eligible or CAS fails or count
    15. * saturated, chain to version with full retry loop.
    16. */
    17. Thread current = Thread.currentThread();
    18. int c = getState();
    19. if (exclusiveCount(c) != 0 &&
    20. getExclusiveOwnerThread() != current)
    21. return -1;
    22. int r = sharedCount(c);
    23. if (!readerShouldBlock() &&
    24. r < MAX_COUNT &&
    25. compareAndSetState(c, c + SHARED_UNIT)) {
    26. //这块代码不用太关心,就主要就是维护了一些加锁次数
    27. if (r == 0) {
    28. firstReader = current;
    29. firstReaderHoldCount = 1;
    30. } else if (firstReader == current) {
    31. firstReaderHoldCount++;
    32. } else {
    33. HoldCounter rh = cachedHoldCounter;
    34. if (rh == null || rh.tid != getThreadId(current))
    35. cachedHoldCounter = rh = readHolds.get();
    36. else if (rh.count == 0)
    37. readHolds.set(rh);
    38. rh.count++;
    39. }
    40. return 1;
    41. }
    42. return fullTryAcquireShared(current);
    43. }
    1. exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current;条件不成立,进入下面的代码块
    2. int r = sharedCount(c);获取高16位的值,读锁加锁次数
    3. !readerShouldBlock() && r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)
      1. readerShouldBlock()
        1. 公平实现:就是判断一下有没有线程在等待着
        2. 非公平实现:返回true,意味着当前线程不是第一个排队的线程,同时队列中第一个等待的线程是独占模式的。返回false意味着前面没有写锁。
      2. r < MAX_COUNT,判断读锁加锁此时有没有超过可加锁的最大值
      3. compareAndSetState(c, c + SHARED_UNIT);用cas修改一下state值,表示加锁成功
    4. fullTryAcquireShared(current);,线程3cas时,线程4也来抢这个读锁,此时线程4是cas不成功的,就要执行当前这个方法。这个方法就是用于同时加读锁,有一个线程失败的情况下,去让加读锁失败的线程去for循环去加锁。
      1. final int fullTryAcquireShared(Thread current) {
      2. /*
      3. * This code is in part redundant with that in
      4. * tryAcquireShared but is simpler overall by not
      5. * complicating tryAcquireShared with interactions between
      6. * retries and lazily reading hold counts.
      7. */
      8. HoldCounter rh = null;
      9. for (;;) {
      10. int c = getState();
      11. if (exclusiveCount(c) != 0) {
      12. if (getExclusiveOwnerThread() != current)
      13. return -1;
      14. // else we hold the exclusive lock; blocking here
      15. // would cause deadlock.
      16. } else if (readerShouldBlock()) {
      17. // Make sure we're not acquiring read lock reentrantly
      18. if (firstReader == current) {
      19. // assert firstReaderHoldCount > 0;
      20. } else {
      21. if (rh == null) {
      22. rh = cachedHoldCounter;
      23. if (rh == null || rh.tid != getThreadId(current)) {
      24. rh = readHolds.get();
      25. if (rh.count == 0)
      26. readHolds.remove();
      27. }
      28. }
      29. if (rh.count == 0)
      30. return -1;
      31. }
      32. }
      33. if (sharedCount(c) == MAX_COUNT)
      34. throw new Error("Maximum lock count exceeded");
      35. if (compareAndSetState(c, c + SHARED_UNIT)) {
      36. if (sharedCount(c) == 0) {
      37. firstReader = current;
      38. firstReaderHoldCount = 1;
      39. } else if (firstReader == current) {
      40. firstReaderHoldCount++;
      41. } else {
      42. if (rh == null)
      43. rh = cachedHoldCounter;
      44. if (rh == null || rh.tid != getThreadId(current))
      45. rh = readHolds.get();
      46. else if (rh.count == 0)
      47. readHolds.set(rh);
      48. rh.count++;
      49. cachedHoldCounter = rh; // cache for release
      50. }
      51. return 1;
      52. }
      53. }
      54. }