一文搞懂各种锁-互斥锁-自旋锁-可重入锁-读写锁-悲观锁-乐观锁-分布式锁

自旋锁、原子锁、互斥锁、信号量

Java中常见的几种锁

说实话,说起Java Hair,我第一次接触的时候是很头疼的。
这些术语与不同的卷曲混合在一起,就像我在读一本新的科幻小说一样。
不过,这么多年摸着石头过河,我有一些很具体的体会。

采集您的头发样本。
之前在做高并发计数器项目的时候尝试过。
当时系统的CPU使用率爆表,检查发现线程正在等待同步块。
改用重量级CPU立刻就减少了毛发,但随后机器就不够用了。
后来他用了钢丝锁,实际上避免了改变核心的状态。
但基准测试显示CPU核心热得冒烟,而且还处于关机末期。
所以这个东西特别适合锁时间很短的场景,比如索引数据库操作。

头发翻转的例子不太可能。
我保留了旧系统。
有些是指在线路上运行的生成函数。
使用反发后,JVM正确报错说已经升级了。
说实话,我当时不太明白。
后来查了资料,发现是单线程触发的。
这种类型的锁对于单线程操作确实没有麻烦,但在多阶段环境中就取决于运气了。

严肃的轻发和重发之间的博弈更为常见。
我开始使用重构闪购模块和同步死锁。
后来我改成了ReentrantLock,并添加了条件变量,吞吐量翻倍了。
有趣的是,测试发现,在这种情况下,错误的锁实际上更快,因为用户请求根本没有来。
但后来上线了,我还是选择了漂亮的锁,因为我怕极端情况下,有的用户永远都拿不到。

最差围栏和足球围栏的竞争证明了对商业的理解。
例如,我推迟了一次表更新。
写操作比读操作多,所以我直接使用了最差的锁定。
结果高峰时线程队列达到1 00+。
后来我把它改成了足球号码加版。
虽然偶尔会有比赛和重试,但总体来说竞争在加剧。
注意,当冲突率小于0.1 %时,最佳锁定更为有效,但具体阈值必须根据场景计算。

我没有亲自跑过这方面的AQS源代码,但是根据经验,可重入锁的可配置性就是它的生命力。
刚接项目的时候,发现某个模块的封闭方案不公平+重入极其不合适,导致年代处于僵局的顶端。
后来改成相等+可重入+可变条件,系统就完全稳定了。
这个东西你不能只靠滚动来记住,你得看数据。