为什么AQS使用双向链表?

最近在看AQS的源码,对AQS使用双向链表作为其同步队列的实现产生了好奇。通过思考和查阅相关资料,AQS使用双向链表应该是处于以下方面的考虑。

中断

在AQS同步队列中,每一个排队的节点都有其对应的线程。如果某一个线程被中断了,那么其对应的节点也应该从同步队列中进行删除。

我们都知道在一个单链表中,当我们想要删除某一个节点(Node2)时,需要知道到其前驱节点(Node1)的指针。在单链表中,我们想要知道当前的节点的前驱节点,必须从单链表的头节点开始遍历。这样一来,每次需要删除一个节点,都需要遍历一整个链表,如果链表长度很长时,性能的开销也会很大。单向链表删除一个节点的过程,如下图所示。

双向链表删除一个节点的过程,并不需要遍历整个链表知道要删除链表的前驱节点,因为要删除的节点本身就持有其前驱节点的指针。删除过程如下图所示。 因此,AQS使用双向链表作为其同步队列的实现,主要还是考虑到双向链表删除节点的时间复杂度要优于单向链表。

经验分享 程序员 微信小程序 职场和发展