多线程与高并发学习笔记(2)

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++的指针

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2020-07-29 22:08  suke_123  阅读(103)  评论(0编辑  收藏  举报