Java内存模型

定义

Java内存模型不是JVM运行时数据区,Java内存模型是由Java语言规范提出,用来描述Java多线程程序在执行时的一些规则,JVM运行时数据区是由Java虚拟机规范提出,用来描述JVM虚拟机的特性。

解决什么问题
  • 所见非所得
  • 无法肉眼去检测程序的准确性
  • 不同的运行平台有不同的表现
  • 错误很难重现
package com.hzw.subject1;

public class DemoVisibility {
    int i = 0;
    boolean isRunning = true;

    public static void main(String[] args) throws InterruptedException {
        DemoVisibility demo = new DemoVisibility();
        new Thread(() -> {
            System.out.println("here i am...");
            while (demo.isRunning) {
                demo.i++;
            }
            System.out.println(demo.i);
        }).start();
        Thread.sleep(3000L);
        demo.isRunning = false;
        System.out.println("shutdown");
    }
}
期望结果:
here i am...
i=..
shutdown

实际结果:
here i am...
shutdown
//当使用32位的JDK且VM options设置为client会得到期望结果
为什么会出现这种情况?

由于JIT编译器对代码性能进行了优化

JIT :编译执行,即将Java代码整体打包进行编译执行,并在编译的过程中对代码性能进行了大量的优化

优化前:
boolean isRunning = true;
while(isRunning) {
		i++:
}

优化后:
//即当程序中一段代码段时间内被多次重复执行,JIT会对其进行优化,使isRunning产生了可见性问题
if(isRunning) {
    while(true) {
        i++:
    }
}
如何解决-volatile同步关键字

可见性问题:让一个线程对共享变量的修改,能够及时的被其他线程看到。共享变量写完其他线程读不到则有可见性问题

Java内存模型规定:对volatile变量v的写入,与所有其他线程后续读取同步,不能够缓存,阻止了一部分(与被修饰的变量相关)的指令重排,可以解决可见性问题

总结

Java内存模型提出Java程序在执行时的一些规则,具体实现规则解决问题是由JVM和虚拟机规范进行

Java内存模型规则
Shared Variables - 共享变量

可以在线程之间共享的内存称为共享内存或堆内存,共享内存用于储存共享变量(实例字段、静态字段、数组元素)

冲突:如果至少有一个访问是写操作,那么对同一个变量的两次访问是冲突的。即使一读一写,当出现可见性问题时也会发生冲突。

线程间操作的定义

线程间操作指:一个程序执行的操作可被其他线程感知或被其他线程直接影响

Java内存模型只描述线程间操作,不描述线程内操作,线程内操作按照线程内语意执行

线程间操作:read、write、lock、unlock、外部操作、线程的第一个和最后一个操作

对于同步的规则定义

对volatile变量v的写入,与所有其他线程后续对v的读同步(可见)

对于监视器m的解锁与所有后续操作对于m的加锁同步(此处m为锁monitor)

对于每个属性写入默认值(0,false,null)与每个线程对其进行的操作同步、

启动线程的操作与线程中的第一个操作同步

线程T2的最后操作与线程T1发现线程T2已经结束同步

如果线程T1中断了T2,那么线程T1的中断操作与其他所有线程发现T2被中断了同步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值