1.volatile理解
volatile是一种轻量级的同步机制
- 保证可见性(主内存被修改,其他线程可见)
- 不保证原子性
- 禁止指令重排
JMM模型:Java Memory Mode,一般保证可见性,原子性,禁止指令重排。
- volatile可见性的证明
import java.util.concurrent.TimeUnit; class ShareData{ volatile int num = 0; public void add60(){ this.num = 60; } } //验证可见性 public class VolatileExample { public static void main(String[] args) { ShareData shareData = new ShareData(); new Thread(() ->{ System.out.println(Thread.currentThread().getName()+"\t come in"); try{ Thread.sleep(3); } catch (Exception e){ e.printStackTrace(); } shareData.add60(); System.out.println(Thread.currentThread().getName()+"\t"+shareData.num); }).start(); new Thread(() ->{ while(shareData.num==0){ } System.out.println(Thread.currentThread().getName()+"\t I know change"); }).start(); } }
可以看到另外一个线程也能知道num被修改了,可见性得到验证。
- volatile不保证原子性,原子性代表着不可被分割,完整性,中间不能被加塞。
class MyData{ volatile int num = 0; public void add(){ num++; } } public class VolatileAtomic { public static void main(String[] args) { MyData myData = new MyData(); for(int i = 1;i<=20;i++){ new Thread(() ->{ for(int j = 1;j<=1000;j++){ myData.add(); } }).start(); System.out.println(Thread.currentThread().getName()+"\t"+String.valueOf(i)); } while(Thread.activeCount()>2){ Thread.yield(); } System.out.println(Thread.currentThread().getName()+myData.num); } } 可以发现最后的结果不是每次都为20000,所以原子性不可被保证。
- 禁止指令重排(cpu会自己做优化),重排时会导致执行顺序被打乱,所以volatile禁止指令重排