newReentrantLock();锁过程://默认执行NonfairSync.lock();finalvoidlock(){//cas0->1,如果操作成功,设置当前线程为独占线程if(compareAndSetState(0,1))setExclusiveOwnerThread(Thread.currentThread());else//如果操作失败acquire(1);}publicfinalvoidacquire(intarg){//tryAcquire(arg)尝试获取锁,获取失败返回false,否则返回trueif(!tryAcquire(arg)&&//尝试获取锁,返回true如果当前线程被中断,否则返回falseacquireQueued(addWaiter(Node.EXCLUSIVE),arg))//获取锁失败,当前线程的中断状态为true,则再次尝试selfInterrupt();}tryAcquire()最后默认调用ReentrantLock.NonfairSync.nonfairTryAcquire();finalbooleannonfairTryAcquire(intacquires){//获取当前线程finalThreadcurrent=Thread.currentThread();//获取状态值intc=getState();//0表示没有线程占用锁if(c==0){//caschange0to1if(compareAndSetState(0,acquires)){//cas成功后,将独占线程变为当前线程setExclusiveOwnerThread(current);//返回成功返回真;}}//如果有线程获取当前线程(即当前线程为独占线程)elseif(current==getExclusiveOwnerThread()){//状态值加1intnextc=c+acquires;if(nextc<0)//溢出thrownewError("Maximumlockcountexceeded");//保存新的状态值setState(nextc);//返回真返回真;}//否则,返回假returnfalse;}AbstractQueuedSynchronizer.addWaiter(Node.EXCLUSIVE);parseprivateNodeaddWaiter(Nodemode){Nodenode=newNode(Thread.currentThread(),mode);}//tail节点赋值给pred;节点pred=tail;//尾节点不为空if(pred!=null){//当前节点prev指针指向当前尾节点node.prev=pred;//cas将当前tail节点替换为node节点if(compareAndSetTail(pred,node)){//当前tail节点的next指针指向node节点pred.next=node;返回节点;}}//如果尾节点为空或者cas替换失败,enq(node);返回节点;}//入队操作:将当前节点设置为尾节点,更新当前节点和替换前尾节点的指针指向privateNodeenq(finalNodenode){for(;;){//赋值尾节点到一个变量Nodet=tail;//如果尾节点为空if(t==null){//创建一个新节点并将其设置为头节点if(compareAndSetHead(newNode()))//将头节点赋给尾节点尾=头;}else{//如果tail节点不为空,则当前节点的prev指针指向tail节点node.prev=t;//cas将当前节点设置为尾节点if(compareAndSetTail(t,node)){//替换前尾节点的next指针指向当前节点t.next=node;返回吨;}}//如果cas替换尾节点失败,循环执行,直到成功}}AbstractQueuedSynchronizer.acquireQueued(addWaiter(Node.EXCLUSIVE),arg);//已经入队的非中断线程尝试获取再次锁定finalbooleanacquireQueued(finalNodenode,intarg){booleanfailed=true;尝试{布尔中断=false;for(;;){//获取当前节点的前一个节点信息finalNodep=node.predecessor();//如果上一个节点信息为头节点,并且成功获取锁if(p==head&&tryAcquire(arg)){//设置当前节点为头节点setHead(node);p.next=null;//帮助GCfailed=false;//返回当前节点的线程中断状态returninterrupted;}//如果当前节点的前驱节点不是头节点或者获取锁失败,则阻塞当前节点线程,等待当前节点线程被唤醒,判断中断状态if(shouldParkAfterFailedAcquire(p,node)&&//阻塞当前线程,等待当前线程唤醒,判断当前线程的中断状态parkAndCheckInterrupt())interrupted=true;}}finally{if(failed)cancelAcquire(node);}}shouldParkAfterFailedAcquire(p,node)详情如下://获取锁失败的线程检查并更新node中的waitStatus,如果该线程应该被阻塞则返回true。privatestaticbooleanshouldParkAfterFailedAcquire(Nodepred,Nodenode){//获取上一个节点的等待状态intws=pred.waitStatus;//-1表示前一个节点被阻塞,需要被唤醒if(ws==Node.SIGNAL)returntrue;if(ws>0){//>0表示取消前一个节点,然后递归查找waitStatus>0的节点信息do{node.prev=pred=pred.prev;}while(pred.waitStatus>0);//找到后,将本节点的next指针指向当前节点pred.next=node;}else{/**waitStatus必须为0或PROPAGATE。表明我们*需要信号,但还没有停车。来电者需要*重试以确保它在停车前无法获取。*waitStatus必须为0或-3(表示可以共享)。表示我们需要唤醒,但还没有被阻塞。调用者需要重试,确保在阻塞操作前无法成功获取操作*///cas将前一个节点的waitStatus改为-1(需要唤醒)compareAndSetWaitStatus(pred,ws,Node.SIGNAL);}//返回假返回假;}privatefinalbooleanparkAndCheckInterrupt(){//阻塞当前线程LockSupport.park(this);//当前线程被唤醒后,判断当前线程的中断状态//这里有一个很重要的知识点:唤醒阻塞线程的方式1.unpark2.interruptreturnThread.interrupted();}
