加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

多线程 – 使用细粒度方法线程安全删除链表节点

发布时间:2020-12-15 05:22:56 所属栏目:Java 来源:网络整理
导读:为什么删除链表中的节点的以下代码段不是线程安全的? 编辑:注意每个节点都有自己的锁 // ... lock acquisition here// ... assumption found to be valid hereprev-next = p-next;p-next = NULL;p-deleted = 1; 解决方法 它是线程安全的,假设你的锁的范围(
为什么删除链表中的节点的以下代码段不是线程安全的?

编辑:注意每个节点都有自己的锁

// ... lock acquisition here
// ... assumption found to be valid here
prev->next = p->next;
p->next = NULL;
p->deleted = 1;

解决方法

它是线程安全的,假设你的锁的范围(意味着它锁定的内容,与C中使用的官方术语“范围”无关)足够大.

如果它只锁定当前节点p,那么你就不能依赖其他线程来进入并使用prev(或者头部或尾部)并因此削弱你.

如果它锁定整个结构,那么是的,它是线程安全的.

我们无法从给出的代码中告诉您锁的范围,但我会提到另一个(无关的)事情.

您可能应该释放p或将其添加到空闲列表以供重复使用.只需将其下一个指针设置为null并将其已删除的标志设置为1,就无法在需要重用它时找到它.这将导致内存泄漏.可能是这样做的代码没有显示,但我想我会提到它,以防万一.

根据您的编辑,您声明您正在使用细粒度方法(每个节点一个锁):

如果您锁定了正在使用或更改的所有三个“节点”,并且将它们锁定在一致的方向上,它仍然是线程安全的.

我把“节点”放在引号中,因为它也适用于头部和尾部指针.例如,如果要删除十节点列表中的第一个节点,则需要按顺序锁定头变量以及第一个和第二个节点.要删除单节点列表中的最后一个节点,需要同时锁定头部和尾部变量以及节点.

锁定所有三个“节点”将防止线程相互产生不利影响.

将它们锁定在一致的方向(例如从头部到尾部)将防止死锁.

但是在尝试改变任何东西之前你必须锁定所有三个.

这甚至会阻止它进行并发插入操作,只要插入锁定插入点两侧的两个“节点”,当然,它们将它们锁定在同一方向上.

不确定在列表上迭代的程度如何.你可能可以使用一个系统,你最初锁定head变量和第一个节点,然后释放头.

然后,当您完成该节点后,在释放当前节点之前锁定下一个节点.这样,您应该能够在不受插入或删除影响的情况下遍历列表,这只能在您当前未使用的区域中进行.

但是,最重要的是,即使使用细粒度锁定范围,您也可以确保线程安全.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读