链表锁机制:从阻塞到非阻塞的演变
1. 延迟同步的特点
延迟同步有其独特的优势,它能够将设置标志这类不太影响整体的逻辑操作,与断开节点这类对结构有较大影响的物理操作分离开来。在简单的例子中,我们一次只断开一个节点,但实际上,延迟操作可以批量进行,并且在合适的时间进行处理,这样能减少对结构物理修改的整体影响。
不过,延迟列表(LazyList)算法也存在明显的缺点,其 add() 和 remove() 方法是阻塞的。也就是说,如果一个线程操作延迟,其他线程可能也会受到影响。
2. 非阻塞同步的引入
有时候,在从列表中物理移除节点之前,先将其标记为逻辑移除是个不错的做法。我们可以进一步扩展这个思路,完全消除锁的使用,让 add() 、 remove() 和 contains() 这三个方法都实现非阻塞。其中,前两个方法是无锁的,最后一个方法是无等待的。
但简单地使用 compareAndSet() 来改变 next 字段是不可行的。例如,当线程A尝试移除节点a,而线程B尝试添加节点b时,可能会出现a被正确删除,但b未被添加到列表中的情况。同样,当两个线程尝试同时移除相邻节点时,也可能导致某个节点未被正确移除。
为了解决这些问题,我们需要确保节点从列表中逻辑或物理移除后,其字段不能被更新。我们的做法是将节点的 next 和 marked 字段视为一个原子单元
超级会员免费看
订阅专栏 解锁全文
5653

被折叠的 条评论
为什么被折叠?



