0、AQS 原理说明

0.1、同步队列(FIFO) - 节点 (ADT)

0.2、同步状态

0.3、锁持有线程

0.4、条件队列(condition)

11、下面结合锁的独占/共享2种特性,以及独占/共享下公平和非公平的具体实现,以及在细化到公平/非公平下的重入和不可重入的具体实现

  1. private transient volatile Node head; // CLH队列的队首
  2. private transient volatile Node tail; // CLH队列的队尾
  3. // CLH队列的节点
  4. static final class Node {
  5. static final Node SHARED = new Node();
  6. static final Node EXCLUSIVE = null;
  7. // 线程已被取消,对应的waitStatus的值
  8. static final int CANCELLED = 1;
  9. // “当前线程的后继线程需要被unpark(唤醒)”,对应的waitStatus的值。
  10. // 一般发生情况是:当前线程的后继线程处于阻塞状态,而当前线程被release或cancel掉,因此需要唤醒当前线程的后继线程。
  11. static final int SIGNAL = -1;
  12. // 线程(处在Condition休眠状态)在等待Condition唤醒,对应的waitStatus的值
  13. static final int CONDITION = -2;
  14. // (共享锁)其它线程获取到“共享锁”,对应的waitStatus的值
  15. static final int PROPAGATE = -3;
  16. // waitStatus为“CANCELLED, SIGNAL, CONDITION, PROPAGATE”时分别表示不同状态,
  17. // 若waitStatus=0,则意味着当前线程不属于上面的任何一种状态。
  18. volatile int waitStatus;
  19. // 前一节点
  20. volatile Node prev;
  21. // 后一节点
  22. volatile Node next;
  23. // 节点所对应的线程
  24. volatile Thread thread;
  25. // nextWaiter是“区别当前CLH队列是 ‘独占锁’队列 还是 ‘共享锁’队列 的标记”
  26. // 若nextWaiter=SHARED,则CLH队列是“独占锁”队列;
  27. // 若nextWaiter=EXCLUSIVE,(即nextWaiter=null),则CLH队列是“共享锁”队列。
  28. Node nextWaiter;
  29. // “共享锁”则返回true,“独占锁”则返回false。
  30. final boolean isShared() {
  31. return nextWaiter == SHARED;
  32. }
  33. // 返回前一节点
  34. final Node predecessor() throws NullPointerException {
  35. Node p = prev;
  36. if (p == null)
  37. throw new NullPointerException();
  38. else
  39. return p;
  40. }
  41. Node() { // Used to establish initial head or SHARED marker
  42. }
  43. // 构造函数。thread是节点所对应的线程,mode是用来表示thread的锁是“独占锁”还是“共享锁”。
  44. Node(Thread thread, Node mode) { // Used by addWaiter
  45. this.nextWaiter = mode;
  46. this.thread = thread;
  47. }
  48. // 构造函数。thread是节点所对应的线程,waitStatus是线程的等待状态。
  49. Node(Thread thread, int waitStatus) { // Used by Condition
  50. this.waitStatus = waitStatus;
  51. this.thread = thread;
  52. }
  53. }

1、独占锁(一):

1.1、获取锁:公平与非公平入队列的步骤以及区别?

1.1.1、公平锁:

1.1.1.1、可重入

1.1.1.2、不可重入

1.1.2、非公平锁:默认

1.1.2.1、可重入

1.1.2.2、不可重入

独占锁模式下,实现非公平可重入的ReentrantLock ,被阻塞线程入队列的区别?
前驱节点 是头节点(队列还没有创建):1、首先T2线程与T1争抢锁时算一次
2.1、判断前驱节点prve 是否为 NULL 头节点。
2.2、创建自己节点初始化队列,再次尝试获取一次。
前驱节点不是 头节点:直接创建节点,入队列,设置前驱节点waitstate = -1;

1.2、释放锁:公平与非公平的步骤以及区别?

1.2.1、公平锁:

1.2.1.1、可重入

1.2.1.2、不可重入

1.2.2、非公平锁:

1.2.2.1、可重入

1.2.2.2、不可重入

2、共享锁(二):

2.1、获取锁:公平与非公平入队列的步骤以及区别?

2.1.1、公平锁:

2.1.2、非公平锁:

2.2、释放锁:公平与非公平的步骤以及区别?

2.2.1、公平锁:

2.2.2、非公平锁: