#并发编程的bug源头
cpu 内存 磁盘
核心矛盾就是三者的速度差别 cpu > 内存 > 磁盘
- 为了解决cpu 增加缓存
- 操作系统增加进程,线程
- 编译器优化计算机的指令
如果有2个线程同时访问cpu中的数据,在单核场景下A线程修改值,B就能发现,这就是可见性。但是要知道一个问题,cpu中是拿到的内存的缓存副本。
##线程切换带来的原子性问题我们把一个或者多个操作在 CPU 执行的过程中不被中断的特性称为原子性。
比如一个count +=1 操作就分成三个指令,1 读取到cpu的缓存中,2寄存器执行加操作,3将结果写入内存(缓存机制导致可能写入的是 CPU 缓存而不是内存)
编译器的指令优化带来并发问题
1 | public class Singleton{ |
拿单例来说明编译器,指令重排说明问题,编译器自己会优化命令。
问题就发生在 new Singleton 这里 ,如果发生指令重排线程切换,那么就带来了并发问题。
- 分配一块内存 M;
- 在内存 M 上初始化 Singleton 对象;
- 然后 M 的地址赋值给 instance 变量。
发生后可能是1,3,2 的顺序
- 然后 M 的地址赋值给 instance 变量。
小结 在采用一项技术的同时,一定要清楚它带来的问题是什么,以及 如何规避。
自旋锁 优点不阻塞,但是消耗cpu资源
怎么自己实现自旋锁?
AutoReference
独占锁/写锁 共享锁/读锁
ReentrantReadWriteLock
##
##
##
本文欢迎转载,但是希望注明出处并给出原文链接。
如果你有任何疑问,欢迎在下方评论区留言,我会尽快答复。
如果你喜欢或者不喜欢这篇文章,欢迎你发邮件到 alonecong@126.com 告诉我你的想法,你的建议对我非常重要。
本文作者: lancecong
联系方式: alonecong@126.com
版权声明: 除特别声明外,所有文章均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!