首页天道酬勤clh队列是什么意思,cloud

clh队列是什么意思,cloud

张世龙 05-04 17:55 92次浏览

文章: https://blog.csdn.net/chens sy/article/details/60781148

AQS摘要说明了AQS内部维护了FIFO队列。 此队列是CLH同步队列。

CLH同步队列是FIFO双向队列,AQS依赖它来管理同步状态。 如果当前线程无法获取同步状态,AQS会将信息(如当前线程等待的状态)生成为节点(Node ),并将其添加到CLH同步队列中。 同时,如果当前线程被阻止且同步状态解除,则唤醒第一个节点,并再次尝试获取同步状态。

在CLH同步队列中,节点表示线程,并包含线程引用(thread )、状态(waitStatus )、前体节点(prev )和后续节点(next )。 定义如下。

静态final class node {/* *共享*/staticfinalnodeshared=new node (; //staticfinalnodeexclusive=null; /**由于超时或中断,节点将设置为取消状态。 已取消的节点不参与冲突。 他不会在取消状态下转移到其他状态。 * /静态final int cancelled=1; /**后续节点线程处于等待状态,如果当前节点线程解除或取消同步状态,则通知后续节点,后续节点线程为*/static final int SIGNAL=-1; /**节点在等待队列中,节点线程在Condition中等待。 在其他线程对Condition调用signal ()后,更改节点从等待队列中继到同步队列,并参与同步状态的获取(*/static final int CONDITION=-2; /**表示以下共享同步状态的获取将无条件传播: * /静态final int propagate=-3; /**等待状态* /电压等待状态; /**前驱节点*/volatile Node prev; /**后继节点*/volatile Node next; /**获取同步状态的线程* /电压阈值线程; 节点下一个服务员; finalbooleanisshared ((returnnextwaiter==shared; } final Node predecessor () throwsnullpointerexception ) nodep=prev; if(p==null ) throw new NullPointerException ); else return p; } Node () } Node ) threadthread,Node mode ) ) { this.nextWaiter=mode; this.thread=thread; }node(threadthread,int waitStatus ) { this.waitStatus=waitStatus; this.thread=thread; }} CLH同步队列的结构图如下。

学习了数据结构的我们,CLH团队要排队并不容易。 但是,tail只是指向新节点,新节点的prev指向当前最后一个节点,当前最后一个节点的next指向当前节点。 代码看看add waiter (节点节点)方法。

专用节点模式//新建节点节点=新节点thread.currentthread ),模式); //末尾节点node pred=尝试添加tail的if(Pred!=null}{node.prev=pred; //CAS尾节点if (比较andsettail (pred,node ) ) { pred.next=node; 返回节点; }//多次尝试enq (节点); 返回节点; }addwaiter(nodenode )快速尝试设定终端节点,失败时调用enq ) nodenode (节点)方法设定终端节点

私有节点(finalnodenode )//多次尝试直到成功); ({节点t=tail; //tail不存在,起始节点if(t==null ) if (compareandsethead (new node ) ) tail=head; } else { //尾节点node.prev=t; if (比较安装(t,node ) ) { t.next=node; 返回t; }}在上述代码中,这两个方法都使用CAS方法compareandsettail(nodeexpect,Node update )设置了终端节点。 这将确保线程安全地添加节点。 在enq(nodenode )方法中,AQS确保“死循环”正确添加节点,只有在成功添加节点时,当前线程才会从该方法返回,否则将一直运行。

流程图如下。

出列

CLH同步队列符合FIFO标准,如果第一个节点的线程解除同步状态,则后续节点(next )将启动,后续节点将在成功获取同步状态时将其自身设置为第一个节点。 该过程非常简单,head运行该节点,断开原始第一个节点的next和当前节点的prev即可。 请注意,在此过程中不需要使用CAS进行保修。 由于同步状态下只能成功获取一个线程,因此进程图如下:

多线程读redis队列,java线程锁有几种