【Java】关于Java内存模型

学习资料来自:

https://blog.csdn.net/yaoyuanbo/article/details/81199154

https://my.oschina.net/u/3728792/blog/3050325

https://blog.csdn.net/qq_32534441/article/details/88386473

简单梳理总结:

问题:Java内存模型(JMM)是什么?

首先要知道内存模型是什么?

我们知道模型都是用来解决问题的对吧,那么内存模型被设计出来肯定也是解决某些问题的,更进一步应该是跟内存有关的问题,那它要解决什么内存上的问题呢

这就要说到CPU和缓存的一致性问题了。

简单的说,我们现在的CPU都是多核的,并且都有多级缓存,结合这个2核的结构图可以找到问题:

在多核CPU上,执行多线程的任务,多个线程访问进程的某个共享内存,每个线程都在不同的核上执行,那么就会在各自的缓存中保存一分共享内存的缓存,就会导致缓存一致性的问题

即,

多核CPU在多线程场景下会存在缓存一致性问题。

还有一种硬件上的问题,为了使处理器内部的运算单元能够尽量的被充分利用,处理器可能会对输入代码进行乱序执行处理。这就是处理器优化。除此之外,很多编程语言的编译器也会有类似的优化,比如Java虚拟机的即时编译器(JIT)也会做指令重排

那么这些在硬件上的问题和软件有什么关系?实际上在并发编程中也有如下几个问题:

  1. 原子性:同一时刻只能有一个线程进行操作,也就是说当一个线程在执行的过程中,不可以被中断。
  2. 可见性:线程对于某个变量的修改能够立刻被其它线程观测到。
  3. 有序性:如果在本线程内观察,所有操作都是有序的;如果在一个线程中观察另一个线程,所有操作都是无序的。也就是说,线程内表现串行,线程间出现指令重排现象。

 这三个问题实际上是之前说的硬件问题的抽象。

到这里问题已经找到了,那我们就知道内存模型就是用来解决这些问题的。

为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范。

内存模型解决并发问题主要采用两种方式:限制处理器优化使用内存屏障。(待补充)

知道了内存模型是什么之后,那么Java内存模型是什么呢?

Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。

Java内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了该线程中使用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主存之间进行数据同步进行。

JMM就作用于工作内存和主存之间数据同步过程它规定了如何做数据同步以及什么时候做数据同步

因此:

JMM是一种规范,目的是解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题。目的是保证并发编程场景中的原子性、可见性和有序性。

 之前说Java内存模型是一种规范,那制定了规范肯定是要实现的,怎么实现呢?

在开发多线程的代码的时候,我们可以直接使用synchronized等关键字来控制并发,从来就不需要关心底层的编译器优化、缓存一致性等问题。所以,Java内存模型,除了定义了一套规范,还提供了一系列原语,封装了底层实现后,供开发者直接使用

我们前面提到,并发编程要解决原子性、有序性和一致性的问题,我们就再来看下,在Java中,分别使用什么方式来保证。

原子性

使用synchronized来保证方法和代码块内的操作是原子性的

可见性

Java内存模型是通过在变量被修改时将新值同步刷新到主存,在变量读取时从主存刷新变量值这种依赖主存作为传递媒介的方式来实现的。

Java中的volatile关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次使用之前都从主内存刷新。因此,可以使用volatile来保证多线程操作时变量的可见性。

除了volatile,Java中的synchronizedfinal两个关键字也可以实现可见性。只不过实现方式不同。

有序性

在Java中,可以使用synchronized和volatile来保证多线程之间操作的有序性。实现方式有所区别:

volatile关键字会禁止指令重排。synchronized关键字保证同一时刻只允许一条线程操作。

好了,这里简单的介绍完了Java并发编程中解决原子性、可见性以及有序性可以使用的关键字。读者可能发现了,好像synchronized关键字是万能的,他可以同时满足以上三种特性,这其实也是很多人滥用synchronized的原因。

但是synchronized是比较影响性能的,虽然编译器提供了很多锁优化技术,但是也不建议过度使用。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值