可见性:
一个线程对共享变量值的修改,能够及时的被其他线程看到
共享变量:
如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量
可见性的实现方式
1.synchronized
2.volatile
synchronized
1.原子性(同步)
2.可见性
JMM关于synchronized的两条规定:
1.线程解锁前,必须把共享变量的值刷新到主内存中
2.线程加锁时,将清空工作内存中的共享变量的值,从而在使用共享变量需要从主内存中重新读取最新的值
线程执行互斥代码的过程
1.获得互斥锁
2.清空工作内存
3.从主内存拷贝变量的最新副本到工作内存
4.执行代码
5.将更改后的共享变量值刷新到主内存
6.释放互斥锁
volatile实现可见性
volatile关键字:
能保证volatile变量可见性
不能保证volatile变量符合操作的原子性
深入来说:通过加入内存屏障和禁止冲排序优化实现的
写volatile变量的过程:
1.改变线程工作内存中的volatile变量副本的值
2.将改变后的副本的值从工作内存刷新到主内存
读volatile变量的过程
1.从主内存读取vloatile变量的最新值到线程的工作内存中
2.从工作内存中读取volatile变量的副本
保持原子性的方法:
1.使用synchronized关键字
1.5后
2.使用ReentrantLock
(java.util.concurrent.locks包下)
3.使用AtomicInterger
(java.util.concurrent.atomic包下)
synchronized和volatile比较
volatile不需要加锁,比synchronized更轻量级,不会阻塞线程;
从可见性上来说,volatile中读相当于加锁,写相当于解锁
synchronized 能保证可见性,原子性
volatile 只能保证可见性