zl程序教程

您现在的位置是:首页 >  其他

当前栏目

【并发编程079】线程安全的非阻塞队列 ConcurrentLinkedQueue?

2023-09-27 14:29:27 时间

线程安全的非阻塞队列 ConcurrentLinkedQueue?

image-20220418160708409

Tail节点并不总是尾节点, 所以每次入队都必须 先通过tail节点来找到尾节点 。尾节点可能 是 tail节点, 也可能是tail节点的next节点。

image-20220418160726045

让tail节点永远作为队列的尾节点, 这样实现代码量非常少, 而且逻辑清晰和易懂 。但是, 这么做有个缺点, 每次 都需要使用循环CAS更新tail节点 。 如果能减少CAS更新tail节点的次 数, 就能提高入队的效率, 所以并不 是每次节 点入队后都将tail节点更新成尾节点, 但是距离越长带来的负面效果就是每次入队时定位尾节点的时间就越长, 因为 循环体需要多循环一次来定位出尾节点, 但是这样仍然能提高入队的效率, 因为从本质上来 看它通过增加对volatile 变量的读操作来减少对volatile变量的写操作, 而对volatile变量的写操 作开销要远远大于读操作, 所以入队效率会有 所提升

image-20220418160835079

首先获取头节点的元素,然后判断头节点元素是否为空, 如果为空, 表示另外一个线程已 经进行了一次出队操作将该节点的元素取走, 如果不为空, 则使用CAS的方式将头节点的引 用设置成null, 如果CAS成功, 则直接返回头节点的元素, 如果不成功,表示另外一个线程已经进行了一次出队操作更新了head节点, 导致元素发生了变化, 需要重新获取头节点。