JAVA高级开发-学习笔记(volatile关键字)

一、变量分为哪几类

全局变量 = 属性(静态的、非静态的)局部变量 = 本地变量、参数

二、多线程间共享数据

全局变量:静态变量或共享对象

三、并发线程能不能看到共享变量的最新值,这就是并发中变量可见性问题

  1. 为什么不可见?
  2. 怎样才能可见
    使用synchroized关键字,对线程主体进行包装
    使用volatile关键字修饰共享变量

四、JAVA内存模型及操作规范

  1. 共享变量必须存放在主内存。
  2. 线程有自己的工作内存,线程只可操作自己的工作内存。
  3. 线程要操作共享变量,需从主内存中读取变量值到工作内存,改变后再从工作内存同步到主内存。
JAVA高级开发-学习笔记(volatile关键字)_第1张图片

五、JAVA内存模型带来的问题

  1. 数据存在多份拷贝,导致多线程同时读写同一变量时,存在数据不准确的问题。即线程安全问题。

  2. 所以要使用线程同步或锁处理。

六、变量在线程1中更改,在线程2中能看到该变量的最新值

  1. 线程1修改A后,必须马上同步回主内存

  2. 线程2使用A前,需要重新从主内存读取到工作内存

七、JAVA内存模型-同步交互协议,规定了8种原子操作

  1. lock(锁定) 将主内存中的变量锁定,为一个线程所独占。
  2. unlock(解锁) 将lock加的锁解除,允许其它线程访问主内存中的该变量。
  3. read(读取) 作用于主内存变量,将主内存中的变量值读取到工作内存(从主内存读取到寄存器)。
  4. load(载入) 作用于工作内存变量,将read读取到的值保存到工作内存中的变量副本中(寄存器变量载入到工作内存)。
  5. use(使用) 作用于工作内存变量,将值传递给线程的代码执行引擎。
  6. assign(赋值) 作用于工作内存变量,将执行引擎处理返回的值重新赋值给变量副本。
  7. store(存储) 作用于工作内存变量,将变量副本的值传送到主内存中(从工作内存读取到寄存器)。
  8. write(写入) 作用于主内存变量,将store传入的值写入到主内存的共享变量中(寄存器变量写入到主内存)。

注意:任意间的组合操作,不是原子的。

  1. 将一根变量从主内存复制到工作内存,要顺序执行read、load操作;要将变量从工作内存同步回主内存要顺序执行stroe、write操作。只要求顺序执行,不一定是连续执行(即原子操作)。
  2. 做了assign操作,必须同步回主内存。不能没做assign操作,同步回主内存。(不一定assign后,马上同步回主内存)

八、并发中保证变量可见性方法final synchronized volatile

九、synchronized语义规范(既可以保证可见性,又可以保证线程安全)

  1. 进入同步块前,先清空工作内存中的共享变量,从主内存中重新加载。
  2. 解锁前,必须把修改的共享变量同步回主内存。
  3. 最核心的,是synchronized有锁机制,只有获得锁的线程才能操作共享资源。(悲观锁)
JAVA高级开发-学习笔记(volatile关键字)_第2张图片

十、 volatile语义规范(保证可见性,保证工作内存的变量和主内存的变量的值一致)

  1. 使用volatile变量时,必须重新从主内存加载,并且read、load是连续的。
  2. 修改volatile变量后,必须马上同步回主内存,并且store、write是连续的。

十一、volatile能做到线程安全吗?(不能保证原子性)

  1. 不能,因为它没有锁机制,线程可并发操作共享资源。
JAVA高级开发-学习笔记(volatile关键字)_第3张图片

十二、volatile比synchronized,使用简单、性能稍好。

十三、volatile还可以用于限制局部代码指令重排序

  1. 线程A和线程B的部分代码

线程A

    content = initContent();
    
    isInit = true;

线程B

while(isinit) {
        content.oper();
    }
  1. jvm优化指令重排序后

线程A(因为两行代码,没有任何关系)

 isInit = true;
    content = initContent();
  1. 当两个线程并发执行时,就可能出现线程B中content发生空异常。

十四、volatile的使用范围

  1. 只可修饰成员变量(静态、非静态)。因为用来保证共享变量可见性,共享变量只能是全局变量。

  2. 多线程并发下,才需要使用。

十五、 单例模式中对volatile关键字的使用

你可能感兴趣的:(JAVA高级开发-学习笔记(volatile关键字))