JMM

suaxi
2021-02-19 / 0 评论 / 56 阅读 / 正在检测是否收录...

JMM

volatile

volatile是Java虚拟机提供的轻量级同步机制

它的三个特性:

  • 保证可见性
  • 不保证原子性
  • 禁止指令重排


JMM相关的一些同步约定:

1、线程解锁前,必须把共享变量立刻刷回主存

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

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


1.JMM四组操作.png

不保证原子性的测试实例:

package com.sw.volatileDemo;

import java.util.concurrent.TimeUnit;

/**
 * @Author suaxi
 * @Date 2021/2/19 22:07
 */
public class JMMTest {
    private static int num = 0;
    public static void main(String[] args) { //main线程

        new Thread(() ->{ //线程1
            while (num == 0){

            }
        }).start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        num = 1;
        System.out.println(num); //输出num=1,main线程将num改为1后,线程1还在循环while(num == 0)
    }
}

2.volatile不保证原子性测试实例.png


JMM对八种指令的使用制定了如下规则:

  • 不允许read和load、store和write操作单独出现,即:使用read必须load,使用store必须write
  • 不允许线程丢弃它最近的assign操作,即:工作变量(工作内存中)的数据改变了之后,必须告知主存
  • 不允许一个线程将没有assign的数据从工作内存同步回主内存
  • 一个新的变量必须在主内存中诞生,不允许工作内存直接使用一个未被初始化的变量,即:对变量进行use、store操作之前,必须经过assign和load操作
  • 一个变量同一时间只有一个线程能对其进行lock。多次lock后,必须执行相同次数的unlock才能解锁
  • 如果对一个变量进行lock操作,会清空所有工作内存中此变量的值,在执行引擎使用这个变量之前,必须重新load或assign操作初始化变量的值
  • 如果一个变量没有被lock,就不能对其进行unlock操作,也不能unlock一个被其他线程锁住的变量
  • 对一个变量进行unlock之前,必须把此变量同步回主内存
0

评论 (0)

取消