解决线程不安全问题的三种方法
一.volatile:轻量级解决“线程安全”的方案
1.作用:
- 禁止指令重排序
- 解决线程可见性的问题,实现原理是当操作完变量之后,强制删除掉线程工作内存中的此变量。
注意事项:
volatile不能解决原子性问题。
二. 线程的工作方式:
(1.)先在自己的工作内存中找变量
(2.)去主内存里面找变量.
三.线程安全问题解决
1.CPU抢占式调度(不能解决,因为CPU抢占是不可控的)
2.每个线程操作自己的变量(可能行)不通用,修改难度大。
3.在关键代码让所有的CPU排队执行,加锁。
(1)锁操作的关键步骤: - 尝试获取( 如果成功拿到锁加锁,排队等待)
- 释放锁
四.Java中解决线程安全问题的方案:
- synchronized 加锁和释放锁 [ JVM 层面的解决方案,自动帮我们进行加锁和释放锁 ]
- Lock手动锁[程序员自己加锁和释放锁]
五 .synchronized注意事项:
在进行加锁操作的时候,同一组业务一定是同一个锁对象。
1.synchronized实现原理:
(1.)操作:互斥锁mutex
(2.)JVM中:帮我们实现的监视器锁的加锁和释放锁的操作。
(3.)在Java层面中:
a)锁对象mutex .
b)锁存放的地方:变量的对象头
2.synchronized说明
synchronized锁机制是非公平锁。
公平锁可以按顺序进行