这个Exchanger 的文章发出去后,有些同事们还是说看不懂。那我就继续图解系列。我们分不同的情况来介绍代码。
初始阶段
image.png此时slot 为null
第一个线程到来
image.png- 把自己threadlocal 的节点 设置成 slot,设置数据
- 把自己阻塞
第二个线程到来
image.png- 发现slot 不为null ,改为null,同时交换数据,slot为thread-1 的node reference ,因此thread1 可以获得数据
- thread 1 unpark, 一个配对完成
第三个线程到来
thread 和thread 2 正在交换中
image.png
- 尝试设置slot 为null, 此时thread 2 正在操作, 失败
- 创建arena 数组
进入到arenaExchange,此时有两种情况
情况1
thread 1, 2, 已经释放, 第四个线程到来
image.pngthread 4 进行了park ,thread 3 可以匹配 thread4 在slotExchange 方法中
则直接返回V.
情况2
thread 1, 2, 没有释放,还在交换。
image.pngthread3占据arena 数组第1 个,并进行park
此时 来了thread 4
thread 1, 2, 没有释放,还在交换。 thread 3 park
image.pngthread 4 找到第一个arena 的thread3, 交换数据,thread 3 unpark.
此时 来了thread 5
thread 1, 2, 没有释放,还在交换。 thread 3, 4 还在交换,
image.png
thread 5 循环尝试更改第一个node(thread3),如果成功就说明可以配对,配对返回。 如果失败走下面。
此时 来了thread 5
thread 修改 第一个node (thread3) 失败,就找到下一个arena array, 设置节点为自己,进行park
image.png
依次类推,如果越界,增加一个容量。
总结
上面只是用图示的方式来表达这个流程。所以新的线程都依次走过的逻辑,符合哪条走哪条。
网友评论