菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
473
0

java面试一日一题:java内存模型

原创
05/13 14:22
阅读数 32109

问题:请讲下java内存模型?

分析:该问题比较容易和jvm内存区域(java内存结构)这样的问题混淆,其实他们是两个概念,jvm内存区域指的是运行时的几块数据区域,包括堆、方法区、虚拟机栈、本地方法栈、程序计数器,强调的是在java程序运行的时候,内存是怎么划分的;而内存模型是另外的一个概念。

回答要点:

主要从以下几点去考虑,

1、java内存模型的作用,保证程序执行的可见性、有序性、原子性;

2、内存模型定义了什么,内存模型定义了多线程读写共享内存的规范;

3、内存模型怎么实现多线程共享变量的读写;

java内存模型简称JMM,是一种规范,通过这些规范定义java程序中各个变量的访问方式,解决并发编程中可能出现的线程安全问题。jvm运行程序的实体是线程,每个线程创建时jvm都会为其创建一个工作内存,用于存放线程私有的数据;Java内存模型规定所有的变量均保存在主内存中,主内存是共享内存,所有的线程都可以访问,但对变量的所有操作(包括读取赋值)都在工作内存中进行,线程无法直接操作主内存中的变量,所以就有了JMM。

主内存

主要存储的是Java实例对象,所有线程创建的实例对象都在主内存中,不管是成员变量还是在方法中创建的局部变量,同时也包含类信息、常量(static final)、静态变量(static)。由于主内存是共享区域,所以多个线程对同一个变量访问就会有线程安全问题;可以把主内存想象为java内存区域的堆、方法区

工作内存

主要存储当前线程正在执行的方法的所有本地变量(工作内存中存储着主内存中变量的副本),工作内存只对当前线程可见,其他线程无法访问当前线程的变量;可以把工作内存想象为Java内存区域的虚拟机栈、本地方法栈、程序计数器;是在java程序运行时的内存;

 

一个实例对象中的成员方法,如果方法中包含本地变量是基本数据类型(8种,boolean byte short int long double float char),这些基本类型的变量存储在工作内存中;如果本地变量是引用类型,那么该变量的引用存储在工作内存中,对象实例则存储在主内存中,对应对象实例中的成员变量不论是基本类型还是引用类型都存储在主内存中;

例,

public class Test{


private void method(){
A ma=new A();
int a=0;

}



}

public class A{
private int a;
private Integer aa;

}

上面的方法method中的ma会存储在工作内存中,a存储在工作内存,而new A()生成的实例存储在主内存中,包括实例中的a也是存储在主内存中;

 

在Java中可以依靠volatile和synchronized关键字来保证可见性、有序性、原子性,除此之外还定义了一套happens-before原则来保证多线程操作时的可见性、有序性、原子性;

程序顺序原则,在一个线程内必须保证语义串行性,也就是按照代码顺序执行;

锁原则,加锁操作必然发生在解锁操作之后(同一把锁);

volatile原则,volatile的写先发生于volatile的读;

。。。

 

先写下分析思路,后续补充详细内容,有不当之处欢迎指正!

 

 

发表评论

0/200
473 点赞
0 评论
收藏
为你推荐 换一批