实现线程安全的队列有两种方式:一种是使用阻塞算法,另外一种是使用非阻塞算法。算法
1.阻塞算法的队列可使用锁的方式来实现。安全
2.非阻塞的实现方法则可使用循环CAS的方式来实现。线程
ConcurrentLickedQueue使用非阻塞的方式实现线程安全队列。是一个基于连接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,添加一个元素的时候,它会添加到队列的尾部;当咱们获取一个元素时,它会返回队列头部的元素。排序
ConcurrentLinkedQueue由head节点和tail节点组成,每一个节点(Node)由节点元素和指向下一个节点(next)的引用组成,节点与节点都是经过next关联起来,从而组成一张链表结构的队列。队列
入队列:循环
入队列主要作两件事: 1.定位出尾节点 2.使用CAS算法将入队列节点设置成尾节点的next节点引用
定位尾节点: tail节点并非尾节点,因此每次入队都必须先经过tail节点来找到尾节点。尾节点多是tail节点,也多是tail节点的next节点。方法
设置入队节点为尾节点: p.casNext(null,n)方法用于将入队节点设置为当前队列尾节点的next节点。若是p是null,表示p是当前队列的尾部节点,若是不为null,表示有其余更新了尾节点,则须要从新获取当前队列的尾部节点。线程安全
出队列:链表
出队列就是从队列里返回一个节点元素,并清空该节点对元素的引用。并非每次出队列都更新head节点,当head节点里有元素的时候,直接弹出head节点里的数据,而不会更新head节点。只有当head节点里没有元素时,出队操做才会更新head节点。
首先获取头节点的元素,而后判断头结点元素是否为空,若是为空,表示另一个线程已经进行了一次出队操做将节点的元素取走,若是不为空,则使用CAS的方式将头结点的引用设置为null,若是CAS成功,则直接返回头结点的元素,若是不成功,表示另一个线程已经进行了一次出队操做更新了head节点,致使元素发生了变化,须要从新获取头部节点。