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