Java内存模型

个人学习总结,能力有限,欢迎纠错。


JMM (Java Memory Model)

JMM主要目的:定义程序中各个变量访问规则(在虚拟机中从内存读取变量或者将变量写入内存)。

内存中存储的变量:实例字段、静态字段、构成数组对象的元素。不包括局部变量方法参数(线程私有,不会被共享)

JMM规定:

        1、所有的变量都存储在主内存中

        2、每条线程都有自己的工作内存

        3、线程的工作内存中保存了该线程使用到的变量在主内存的副本拷贝

        4、线程对变量的所有操作都必须在工作内存中进行,不能直接读写主内存中的变量。



线程、工作内存、主内存交互

工作内存与主内存的8中基本操作:

        lock(锁定):作用于主内存的变量,把一个变量标识为一条线程独占的状态

        read(读取):作用于主内存的变量,把一个变量的值从主内存传输到工作内存

        load(载入):作用于工作内存的变量,将read传输过来的变量值赋值给工作内存的变量副本

        use(使用):作用于工作内存的变量,将工作内存的变量值传递给执行引擎

        assign(赋值):作用于工作内存的变量,将从执行引擎获取到的值赋值给工作内存中的变量

        store(存储):作用于工作内存的变量,把工作内存中的变量值传递给主内存

        write(写入):作用于主内存的变量,把store传输过来的变量值写入主内存的变量中

        unlock(解锁):作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程使用

工作内存与主内存的8种操作必须满足的规则:

        1、如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作初始化变量的值 

        2、变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复使用,多次执行lock后,只有执行相同次数的unlock,变量才会被解锁

        3、对一个变量执行unlock操作之前,必须先把此变量同步会主内存  

        4、如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作,也不允许unlock一个被其他线程锁定住的变量  

        5、read和load、store和write 这两种组合操作不能单独出现(不允许一个变量从主内存读取工作内存不接受或者工作内存发起会写主内存不接受)

        6、变量在工作内存中改变后必须同步回主内存

        7、一个新的变量只能在主内存中诞生。

JMM之原子性:

1、线程访问变量涉及到read、load、use、assign、store、write操作,这些操作都为原子性操作

2、多线程访问共享变量涉及到lock、read、load、use、assign、store、write、unlock。synchronized关键字的指令monitorenter和monitorexit会隐式的调用lock和unlock操作

JMM之可见性:

1、线程解锁前,必须把共享变量的值刷新回主内存

2、线程加锁前,必须读取主内存的最新值到工作内存

3、加锁和解锁是同一把锁

JMM之有序性:

1、在本线程内访问变量,所有的内存操作都为串行操作(即有序)

2、多线程访问变量,多个线程的内存操作会被指令重排序或者工作内存与主内存同步延迟造成无序。

synchronized:

    保证原子性:synchronized对变量的内存操作为lock、read、load、use、assign、store、write、unlock,这些操作都为原子性操作

    保证可见性:synchronized的字节码monitorexit会调用unlock操作,在unlock操作前会把工作内存中的变量值回写到主内存中

    保证有序性:synchronized会调用lock与unlock操作,即便在多线程环境下,变量也只能由一个线程有序的执行内存操作 ,继而实现有序性

volatile:

    保证可见性:volatile修饰的变量在工作内存中修改后能够很快的写回主内存,其他线程从主内存访问新值

    保证有序性:volatile禁止指令重排序

    不能保证原子性

你可能感兴趣的:(Java内存模型)