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

  1. 变量分为哪几类安全

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

  2. 多线程间共享数据多线程

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

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

    (1) 为何不可见?性能

    (2) 怎样才能可见优化

    使用synchroized关键字,对线程主体进行包装spa

    使用volatile关键字修饰共享变量线程

  4. JAVA内存模型及操做规范code

    (1) 共享变量必须存放在主内存。

    (2) 线程有本身的工做内存,线程只可操做本身的工做内存。

    (3) 线程要操做共享变量,需从主内存中读取变量值到工做内存,改变后再从工做内存同步到主内存。

5. JAVA内存模型带来的问题

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

(2) 因此要使用线程同步或锁处理。

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

    (1) 线程1修改A后,必须立刻同步回主内存

    (2) 线程2使用A前,须要从新从主内存读取到工做内存

  2. 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后,立刻同步回主内存)

  3. 并发中保证变量可见性方法 final synchronized volatile

  4. synchronized语义规范(既能够保证可见性,又能够保证线程安全)

    (1) 进入同步块前,先清空工做内存中的共享变量,从主内存中从新加载。

    (2) 解锁前,必须把修改的共享变量同步回主内存。

    (3) 最核心的,是synchronized有锁机制,只有得到锁的线程才能操做共享资源。(悲观锁)

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

    (1) 使用volatile变量时,必须从新从主内存加载,而且read、load是连续的。

    (2) 修改volatile变量后,必须立刻同步回主内存,而且store、write是连续的。

  2. volatile能作到线程安全吗?(不能保证原子性)

    (1) 不能,由于它没有锁机制,线程可并发操做共享资源。

  1. volatile比synchronized,使用简单、性能稍好。
  2. volatile还能够用于限制局部代码指令重排序

(1) 线程A和线程B的部分代码

线程A
    content = initContent();
    
    isInit = true;
复制代码
线程B
    while(isinit) {
        content.oper();
    }
复制代码

(2) jvm优化指令重排序后

线程A(由于两行代码,没有任何关系)
    isInit = true;
    content = initContent();
复制代码

(3) 当两个线程并发执行时,就可能出现线程B中content发生空异常。

  1. volatile的使用范围

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

    (2) 多线程并发下,才须要使用。

  2. 单例模式中对volatile关键字的使用

相关文章
相关标签/搜索