线程安全问题的原因
1:抢占式执行,随机调度
解决方法:加锁
2:多个线程同时修改用一个变量,修改相同的资源
解决方法:
3:修改操作不是原子的
4:内存可见性
5:指令重排序
死锁
场景1:锁是不可重入锁,并且一个线程针对一个锁对象,连续加锁两次
解决方法:通过引入可重入锁
场景2:两个线程两把锁
场景3:N个线程M把锁
如何避免死锁问题?(面试问题)
1:锁具有互斥特性(基本特点,一个线程拿到锁之后,其他线程就得阻塞等待)
2:锁不可抢占(不可被剥夺)(一个线程拿到锁之后,除非自己主动释放锁,否则别人抢不走)
3:请求和保持(一个线程拿到一把锁之后,不释放这个锁的前提下再尝试获取其他锁)
如何解决:不要让锁嵌套获取
4:循环等待(多个线程获取多个锁的过程中,出现了循环等待。a等待b,b等待a)
如何解决:破处循环等待,即使出现嵌套也不会死锁
任何一个死锁的场景必然会同时具备上述四点,缺少一个都不会构成死锁。
当代码中确实需要用到多个线程多把锁,一定要约定好加锁顺序,避免死锁