• 读锁被唤醒时,会去判断队列里面自己的下一个节点是否也是读锁(shard属性),如果是就会一起唤醒,直到遇到一个写锁就终止。iShot2021-01-31 23.56.25.png
    1. import java.util.concurrent.TimeUnit;
    2. import java.util.concurrent.locks.Condition;
    3. import java.util.concurrent.locks.Lock;
    4. import java.util.concurrent.locks.ReentrantLock;
    5. import java.util.concurrent.locks.ReentrantReadWriteLock;
    6. @Slf4j(topic = "enjoy")
    7. public class Lock2 {
    8. //读写锁
    9. static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    10. static Lock r = rwl.readLock();
    11. static Lock w = rwl.writeLock();
    12. public static void main(String[] args) throws InterruptedException {
    13. /**
    14. * t1 最先拿到写(W)锁 然后睡眠了5s
    15. * 之后才会叫醒别人
    16. */
    17. Thread t1 = new Thread(() -> {
    18. w.lock();
    19. try {
    20. log.debug("t1 +");
    21. TimeUnit.SECONDS.sleep(5);
    22. log.debug("5s 之后");
    23. } catch (InterruptedException e) {
    24. e.printStackTrace();
    25. } finally {
    26. w.unlock();
    27. }
    28. }, "t1");
    29. t1.start();
    30. TimeUnit.SECONDS.sleep(1);
    31. /**
    32. * t1在睡眠的过程中 t2不能拿到 读写互斥
    33. * t2 一直阻塞
    34. */
    35. Thread t2 = new Thread(() -> {
    36. try {
    37. r.lock();
    38. log.debug("t2----+锁-------");
    39. TimeUnit.SECONDS.sleep(1);
    40. } catch (Exception e) {
    41. e.printStackTrace();
    42. } finally {
    43. log.debug("t2-----解锁-------");
    44. r.unlock();
    45. }
    46. }, "t2");
    47. t2.start();
    48. TimeUnit.SECONDS.sleep(1);
    49. /**
    50. * t1在睡眠的过程中 t3不能拿到 读写互斥
    51. * t3 一直阻塞
    52. * 当t1释放锁之后 t3和t2 能同时拿到锁
    53. * 读读并发
    54. */
    55. Thread t3 = new Thread(() -> {
    56. try {
    57. r.lock();
    58. log.debug("t3----+锁-------");
    59. TimeUnit.SECONDS.sleep(1);
    60. } catch (Exception e) {
    61. e.printStackTrace();
    62. } finally {
    63. log.debug("t3----释放-------");
    64. r.unlock();
    65. }
    66. }, "t3");
    67. t3.start();
    68. /**
    69. * 拿写锁
    70. * t1睡眠的时候 t4也页阻塞
    71. * 顺序应该 t2 t3 t4
    72. */
    73. Thread t4 = new Thread(() -> {
    74. try {
    75. w.lock();
    76. log.debug("t4--------+---");
    77. TimeUnit.SECONDS.sleep(10);
    78. log.debug("t4--------醒来---");
    79. } catch (Exception e) {
    80. e.printStackTrace();
    81. } finally {
    82. log.debug("t4--------解锁---");
    83. w.unlock();
    84. }
    85. }, "t4");
    86. t4.start();
    87. /**
    88. *
    89. * t5 是读锁
    90. * 他会不会和t2 t3 一起执行
    91. */
    92. Thread t5 = new Thread(() -> {
    93. try {
    94. r.lock();
    95. log.debug("t5--------+锁---");
    96. } catch (Exception e) {
    97. e.printStackTrace();
    98. } finally {
    99. log.debug("t5--------解锁---");
    100. r.unlock();
    101. }
    102. }, "t5");
    103. t5.start();
    104. }
    105. }