//2. cas 更新 state 值,从 0 变成 1 finalvoidlock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); }
1 2 3 4 5
//3. 使用 cas 方式修改 state 的值,如果是第一个线程执行,返回 true .代表已经获得了锁 protectedfinalbooleancompareAndSetState(int expect, int update) { // See below for intrinsics setup to support this return unsafe.compareAndSwapInt(this, stateOffset, expect, update); }
1 2 3 4 5 6 7 8 9
//4. 设置锁的持有者为当前线程 //这里是返回 true . if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread());
//设置当前线程为锁的持有者的 set 方法 protectedfinalvoidsetExclusiveOwnerThread(Thread thread) { exclusiveOwnerThread = thread; }
// 12. // 第一次循环 // 12.1 定义 ws waitStatus 此处 waitStastus=0 // 12.2 执行 else 的逻辑,把 pre.waitStatus 的值修改为 Node.SIGNAL(-1) // 12.3 返回 false // 第二次循环 // ws = pred.waitStatus 等于 Node.SIGNAL 返回 true // 执行 parkAndCheckInterrupt 方法 privatestaticbooleanshouldParkAfterFailedAcquire(Node pred, Node node) { intws= pred.waitStatus; if (ws == Node.SIGNAL) /* * This node has already set status asking a release * to signal it, so it can safely park. */ returntrue; if (ws > 0) { /* * Predecessor was cancelled. Skip over predecessors and * indicate retry. */ do { node.prev = pred = pred.prev; } while (pred.waitStatus > 0); pred.next = node; } else { /* * waitStatus must be 0 or PROPAGATE. Indicate that we * need a signal, but don't park yet. Caller will need to * retry to make sure it cannot acquire before parking. */ compareAndSetWaitStatus(pred, ws, Node.SIGNAL); } returnfalse; }
1 2 3 4 5
//13. park 当前执行的线程 privatefinalbooleanparkAndCheckInterrupt() { LockSupport.park(this); return Thread.interrupted(); }
//18. 释放锁 //18.1 判断 node.waitStatus 的值,此时值是 -1 //18.2 获得当前节点的下一个节点 //18.3 判断当前的节点的值是否为 null 和 s.waitStatus>0 此处条件不满足,s.waitStatus=0 //18.4 如果 s !=null 唤醒节点的线程。 privatevoidunparkSuccessor(Node node) { /* * If status is negative (i.e., possibly needing signal) try * to clear in anticipation of signalling. It is OK if this * fails or if status is changed by waiting thread. */ intws= node.waitStatus; if (ws < 0) compareAndSetWaitStatus(node, ws, 0);
/* * Thread to unpark is held in successor, which is normally * just the next node. But if cancelled or apparently null, * traverse backwards from tail to find the actual * non-cancelled successor. */ Nodes= node.next; if (s == null || s.waitStatus > 0) { s = null; for (Nodet= tail; t != null && t != node; t = t.prev) if (t.waitStatus <= 0) s = t; } if (s != null) LockSupport.unpark(s.thread); }