Java内存模型JMM与Volatile

1.什么是JMM?

​ JMM 是Java内存模型( Java Memory Model),简称JMM

2.JMM的三大特性:
JMM的三大特性:原子性、可见性、有序性。

1.原子性

一个或多个操作,要么全部执行,要么全部不执行(执行的过程中是不会被任何因素打断的)。

2.可见性

只要有一个线程对共享变量的值做了修改,其他线程都将马上收到通知,立即获得最新值。

3.有序性

有序性可以总结为:在本线程内观察,所有的操作都是有序的;而在一个线程内观察另一个线程,所有操作都是无序的

指令重排:我们正常写的代码是按照从上往下的顺序执行的,但是编译器可能为了优化代码会对我们写的代码重新排序,这种操作单线程下基本没问题,但是多线程下就可能会出现有序性问题

有序性问题 指的是在多线程的环境下,由于执行语句重排序后,重排序的这一部分没有一起执行完,就切换到了其它线程,导致计算结果与预期不符的问题。这就是编译器的编译优化给并发编程带来的程序有序性问题。

二.volatile

被volatile修饰的变量有两个特点:有序性,可见性

内存屏障,通过volatile来实现,就是说,当volatile修饰一个变量时,这个变量的上下就带上了内存屏障

volatile特性

1.可见性

  • ①. 保证不同线程对这个变量进行操作时的可见性,即变量一旦改变所有线程立即可以看到

  • ②. 代码展示
    不加volatile,没有可见性,程序无法停止
    加了volatile,保证可见性,程序可以停止

    package now;
    
    import java.sql.Time;
    import java.util.concurrent.TimeUnit;
    
    class Student{
        int age = 0;
        //volatitle int age = 0;
    
        public void changeage(){
            this.age = 50;
        }
    }
    
    /**
     * 验证volatile的可见性
     * 假如 int age = 0;  age变量前面没有用volatile 关键字 修饰
     * volatile可以保证可见性,及时通知其他线程,主物理内存的值已经被修改
     */
    public class VolatileTest {
        public static void main(String[] args) { //main是一切方法的运行入口
    
            Student student = new Student(); //学生类
            // AAA 第一个线程
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t come in");
                //暂停一会线程
                try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
                student.changeage();
                System.out.println(Thread.currentThread().getName() + "\t change age to " + student.age);
            }, "AAA").start();
    
            // main 第二个线程
            while(student.age == 0){
                //main线程 循环等待student.age的变化 知道age不等于0
            }
    
            System.out.println(Thread.currentThread().getName() + "\t mission over" + student.age);
        }
    }
    
    
    

2.无原子性 

 volatile只能保证拿到的数据是最新的,假如在上图的数据加载和数据赋值之间时值改变了,那么这个线程就会作废,导致缺少线程,所以无法实现原子性,下图输出小于1000

 

 3.有序性

在哪些地方可以使用volatile?

●① 单一赋值可以,but含复合运算赋值不可以(i++之类)

1.volatile int a = 10
2.volatile boolean flag = false

●②. 状态标志,判断业务是否结束

为什么有volatile就会加上内存屏障,怎么实现的?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值