java 内存模型

缓存一致性问题

单核cpu,单线程下,cpu独占缓存,操作数据时,不会出现访问冲突问题。

单核cpu,多线程下,进程中的多个线程访问进程内的共享数据,cpu会将内存中的某块数据复制到缓存中,但在某一时刻,cpu只能操作一个线程,即使访问统一数据,也不会发生访问冲突。

多核cpu,多线程下,线程的执行时可以并行的,而cpu会在各自的缓存中保留一份共享内存的数据,所以并行情况下,对同一数据的操作可能会引发问题。

所以说,在cpu和主存之间添加缓存,在多线程的环境下,可能会引发缓存一致性问题。也就是每个cpu缓存中对同一份数据的存储可能不一致。

处理器优化和指令重排

处理器优化是指为了使处理器的运算单元被尽可能的利用,会对指令进行乱序处理。

很多编译器,例如java虚拟机的即时编译器也有类似的操作,就是指令重排,在不影响结果的情况,对代码的执行顺序进行重新排列执行。

并发编程的问题

原子性问题、可见性问题、有序性问题,这些是抽象定义的,也就是前面的处理器优化、缓存一致性、指令重排所导致的问题。

原子性:简单来说就是一个指令不能再分割,要么执行成功,要么不执行。

可见性:当多个线程访问同一变量的时候,一个线程改写了变量,其他线程能立即看得到新修改的值。

有序性:程序执行按照代码的顺序。

什么是内存模型

为了保证并发编程满足原子性、可见性、有序性,提出了一种模型 ---- 内存模型。

为共享内存系统中多线程程序访问数据提供了一个读写操作规范,从而保证指令执行的正确性。

主要有两种方式:限制处理器优化和使用内存屏障

什么是 java 内存模型

java程序运行在java虚拟机上,java内存模型(JMM)是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异,保证java程序在各种平台上对内存访问效果一致的机制和规范。

JMM 规定了所有变量都存于主存中,而每个线程自己的工作内存,保存的是需要用到的变量的对于主存的副本拷贝,而线程不能直接操作主存内的数据,只能操作自己工作内存的变量,不同线程间也无法访问对方的数据,而是通过主存进行数据传递。

JMM作用于工作内存和主存之间的数据同步过程。

JMM是一种规范,目的是为了解决多线程访问共享数据,导致各线程本地内存数据不一致问题,以及编译器对指令重排、处理器优化对指令乱序执行带来的问题。

Java 内存模型的实现

java内存模型封装了底层的实现后提供了一些关键字供开发者使用。

原子性:JVM提供了两个指令monitorenter、monitorexit,对应于java提供的 synchronized 关键字,所以靠 synchronized 关键字满足原子性;

可见性:被 volatile 关键字修饰的变量每次修改变量后都会立即同步到主存,每次读取变量都会从主存中刷新变量值。除此之外,synchronized 关键字和 final 关键字也可以实现可见性,只不过实现方式不同。

有序性:volatile 关键字可以防止指令重排以保证有序性,而synchronized 关键字可以保证同一时刻只执行一个线程。

所以 synchronized 关键字可以满足所有,但是并一定选它就是最好的,因为比较影响性能。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值