请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

Statck类中pop方法与WeakOrderedQueue 中的add 方法之间的同步问题?

请问下,老师:

  1. 在 add 方法中, 会修改 weakorderqueue对象的tail 指针与 link 对象 的next 指针。
  2. 在Stack 类中的pop 方法中,会读取上面的tail 与next 指针
  3. 以上操作是在两个不同的线程中执行, 为什么不在Link 类中的next 域加上volatile ,在WeakOrderQueue 中的tail 域加上volatile ? 怎么解释?
  4. 难道是因为 作者在add 方法中的最后一行调用了这个方法:
    // we lazy set to ensure that setting stack to null appears before we unnull it in the owning thread;
    // this also means we guarantee visibility of an element in the queue if we see the index updated
    tail.lazySet(writeIndex + 1);
  5. 作者对 Recycler 的设计有很多地方值得参考,为了避免加锁,才设计了这样队列式的WeakOrderQueue数据结构,而且保证其head指针可以指向至少一个 Link 对象节点。Link 里又放了一个数组,批量分配空间,避免自身管理数据结构的内存分配开销。并充分利用了ThreadLocal ,首先Stack 是对象生成线程局部的,而且将每个WeakOrderQueue 节点 与对应的Stack 又放在回收线程的ThreadLocal 的map 里,这样每个回收线程互不影响add 操作,只是在new 一个WeakOrederQueue 节点时 并插入到Stack 的头部时候,加了锁,防止写写冲突, 而对于需要遍历WeakOrderQueue 链表的 读线程,不需要加锁,只需要把head 声明成volatile 的. 这时我的理解
  6. 我的问题主要在第3点

正在回答 回答被采纳积分+3

1回答

闪电侠 2019-09-05 23:31:18

这个问题提的非常棒,你的理解也非常正确,这边为了防止线程冲突,用了很多 FastThreadLocal 变量,使得每个线程都有自己局部的 Stack,互不影响,然后每个 Stack 中的元素有可能被其他线程进行回收,每个其他线程都会有一个 WeakOrderQueue 与个 Stack 关联,然后这些 WeakOrderQueue 通过以 head 为头的节点串起来,因此,多个线程的并发关系,只有可能发生的 head 节点上,每个线程维护的 WeakOrderQueue 都是相互独立的,不会受到影响;

0 回复 有任何疑惑可以回复我~
  • 提问者 triump #1
    老师,我想问题的是:
    在 add 方法中, 会修改 weakorderqueue对象的tail 指针与 link 对象 的next 指针。
    在Stack 类中的pop 方法中,会读取上面的tail 与next 指针
    以上操作是在两个不同的线程中执行, 为什么不在Link 类中的next 域加上volatile ,在WeakOrderQueue 中的tail 域加上volatile ? 怎么解释?
    回复 有任何疑惑可以回复我~ 2019-09-05 23:35:09
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信