crossoverJie/JCSprout

上下文切换通常的解决方案中的第一种不叫无锁编程

yongjianmeng opened this issue · 5 comments

在提交issue之前请回答以下问题,谢谢!

建议首先查看是否已经有类似的 Issues (提交时可删除该提示)

你使用的是哪个版本

最新版

预期结果

Java 多线程常见问题中,提到上下文切换通常的解决方案中的第一个方案不是无锁编程。

实际结果

应该叫锁分段技术,加入两个不同的线程被Hash(id)到同一个分段上,也要加锁才能保证线程安全。

重现结果的步骤

其他相关信息

应该叫锁分段技术,加入两个不同的线程被Hash(id)到同一个分段上,也要加锁才能保证线程安全。

@yongjianmeng

分段的主要目的就是为了各个线程自己取自己所管理的分段数据。

可以查看这里的应用:

https://crossoverjie.top/2018/10/31/java-senior/concurrent-in-action2/#%E9%81%8D%E5%8E%86%E6%95%B0%E6%8D%AE%E6%96%B9%E6%A1%88

这样不会有多个线程去竞争一个分段的数据。

你说的分段锁是 1.7 中 ConcurrentHashMap 所采用的,他之所以叫分段锁以及和刚才提到的 Hash(ID) 分段 有个很主要的区别是:

ConcurrentHashMap 是为了存放数据线程是固定的,多线程写入时无论分多少段都可能会出现 N 个线程并发写入一个分段,所以得加锁。

上面提到的是由于数据是固定的,如何让多个线程高效的读取数据并且互相不需要加锁,所以叫无锁编程。

哦哦,我明白你的意思了。但我觉得这里表达得不是特别清楚,容易造成混乱,这里的id是什么id?是线程id吗?如果是的话,怎么保证线程一定能把所有数据分段都覆盖到呢?万一两个线程id覆盖到同一个数据分段呢?可不可以这么说,把数据按照线程个数进行分段,每个线程分配一个数据分段,每个线程处理各自的数据分段?讲道理这里应该是均分,而不是hash crossoverJie notifications@github.com于2018年11月7日 周三21:33写道:

应该叫锁分段技术,加入两个不同的线程被Hash(id)到同一个分段上,也要加锁才能保证线程安全。 @yongjianmeng https://github.com/yongjianmeng 分段的主要目的就是为了各个线程自己取自己所管理的分段数据。 可以查看这里的应用: https://crossoverjie.top/2018/10/31/java-senior/concurrent-in-action2/#%E9%81%8D%E5%8E%86%E6%95%B0%E6%8D%AE%E6%96%B9%E6%A1%88 这样不会有多个线程去竞争一个分段的数据。 你说的分段锁是 1.7 中 ConcurrentHashMap 所采用的,他之所以叫分段锁以及和刚才提到的 Hash(ID) 分段 有个很主要的区别是: ConcurrentHashMap 是为了存放数据线程是固定的,多线程写入时无论分多少段都可能会出现 N 个线程并发写入一个分段,所以得加锁。 上面提到的是由于数据是固定的,如何让多个线程高效的读取数据并且互相不需要加锁。 — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#122 (comment)>, or mute the thread https://github.com/notifications/unsubscribe-auth/AoBP7AU1C7c8BKXjMfj_n5MnxtzjfP6pks5usuEPgaJpZM4YSaiJ .

这个 ID 通常是数据的唯一ID,而 Hash 只是散列的一种方式。简单来说直接用 ID 的尾数与线程数取模也是可以的。

Hmm……如果说数据大小是固定的,那我觉得把数据按照线程数做个分段,每个线程处理对应分段,这样效率更高,不用每次都做取模计算,

是的,当然不是每次都做取模运算,在做具体处理之前就已经分配好了,具体还是建议看看这个吧。

https://crossoverjie.top/2018/10/31/java-senior/concurrent-in-action2/#%E9%81%8D%E5%8E%86%E6%95%B0%E6%8D%AE%E6%96%B9%E6%A1%88