1、volatile的作用
不加volatile程序一直执行,加了程序过一秒执行完毕。
作用:
1、保证线程可见性
在mian线程中修改了running为false,但是在t10线程中不知道running是否修改为false。
本质是:查-MESI cpu的缓存一致性协议
2、禁止指令重排序
2、单例
饿汉式
懒汉
懒汉模式,双重检查保证线程安全
上面程序是错误的,需要加volite
如果不加,会出现指令重排序。
解析:Instance = new Mgr03();
JVM编译完这个指令分三步:1、给这个对象申请内存 2、给这个对象的成员变量初始化 3、把这个对象赋值给Instance。
如果发生指令重排序,那么就不会执行第二步。也就是这个值在半初始化的时候就已经赋值给Instance这个变量了。
cpu加了读屏障LoadFence和写屏障StoreFence
假如在超高并发的时候,一个线程进去,发生了指令重排序,发现这个对象已经有值了,不会进入锁里面的业务逻辑代码。
那么这个对象中变量并没有赋值成我们想要的值。
对象创建并赋值的过程。
3、synchronized能保证原子性,而volatile不能保证
4、锁优化,同步代码块中锁越少越好
5、锁定某对象o,如果o的属性发生改变,不影响锁的使用,但是如果o变成另外一个对象,则锁定的对象发生改变,应该避免将锁定对象的引用变成另外一个对象。
final Object o = new Object();
6、CAS(无锁优化 自旋 乐观锁)
1 count.incrementAndGet();
2
3 public final int incrementAndGet() {
4 return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
5 }
6
7 public final int getAndAddInt(Object var1, long var2, int var4) {
8 int var5;
9 do {
10 var5 = this.getIntVolatile(var1, var2);
11 } while(!this.compareAndSwapInt(var1, var2, var5, var5 +
12 var4));
13
14 return var5;
15 }
16
17 public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
7、ABA问题
解决方法:加version
A-1.0
B-2.0
C-3.0
cas(version,var1,var2)
AtomicStampedReference
如果产生了ABA问题,会不会有什么问题?
如果是基本数据类型不会。
如果是引用类型,你的女朋友跟你复合,中间经历了别的男人。
unsafe这个类相当于c和c++的指针