java-多线程之-Volatile

Volatile用途:
1.线程可见性
2.防止指令重排序
3.dcl单例需要加Volatile吗?
   double lock 后需要再加Volatile吗?


1.线程可见性
 
 1.1 jmm对于内存的处理是4步:

   1.从内存中把值读过来
   2.对值进行修改
   3.如果原来的这个内容没有别标记为 volatile,那么你对值的修改只是本地缓存。
    4.如果有另一个缓存也读了这个,你的修改是不被看见的。

java-多线程之-Volatile

 1.2.volatile 使用

   子线程能否看到主线程里的flag?没加volatile

   java-多线程之-Volatile

  答案:肯定看不到


2.防止指令重排序

首先要明白cpu乱序执行是什么。
     1.指令1  1.1去内存读数据
                   1.2返回数
     2.指令2

   1慢,2 快时,执行顺序,有可能1.1 -2 -1.1 这样执行,而不一定是1.1->1.2->2
    前提:指令1 指令2 无因果关系

 as if serial:在单线程里,无论是第二条先执行还是第一条先执行,最终结果是一样的。看上去像序列化,但不一定是。

java-多线程之-Volatile


3.dcl单例需要加Volatile吗?
   
double lock 后需要再加Volatile吗?

   3.1对象创建
     new 对象的时候有3条语句构成

   1.new 在堆里申请了一块内存,大小: t对象的大小 ,m :=0 默认值
   2.init  初始化    m:8
   3.sdtore_i 建立连接  栈里的小t与内存建立链接java-多线程之-Volatile

   3.2单例
java-多线程之-Volatile

单例是一个类对象,只能有一个,不可能有第二次。有以下三个特点:

2.1构造方法:private
2.2使用单例    getInstance()
2.3 无论调用多少次,肯定都是一个对象。
我需要的时候才new
1.我定义,但不new
2.何时new ? 调用getInstance()时

java-多线程之-Volatile

  多线程时,访问的时候并非同一个对象

 如何解决?

double check lock 可以, 上锁前后都判空

java-多线程之-Volatile

DCL单例(Double Check Lock)到底要不要加volatile?
答案是肯定的。理由:
指令重排
 java-多线程之-Volatile

 原来是0-4-7
 现在是0-7-4

java-多线程之-Volatile

thread2 使用了半初始化状态的对象  本想拿到8 现在拿到了0
所以还是要加的。   

哇,终于写完了。这个看起来很容易,说清楚还是费了点事。