java内存模型

java 内存模型jmm:

java内存模型(即java memory model,简称jmm)本身是一种抽象的概念,并不真实存在,它描述的是一组规则和规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。java内存分为主内存和线程自己的工作内存,线程对变量的修改则需要从主内存中copy变量到自己的工作内容,操作完毕之后将变量放回主内存。

jmm中的主内存:

存储java实例对象,包括类里的成员变量,类信息,常量,静态变量等信息,由于主内存是共享数据区,所以当多条线程操作共享变量时就会出现线程安全问题。

jmm中的工作内存:

存储当前方法的所有本地变量信息,本地变量对其他线程不可见,包括字节码行号指示器,native方法信息,因为工作内存属于线程私有数据去油,不存在线程安全问题。

主内存与工作内存的数据存储类型以及操作方式:

方法里的基本数据类型本地变量将直接存储在工作内存的栈帧中,引用类型的本地变量,引用存储在工作内存中,实例存储在主内存中,成员变量,static变量,类信息均会被存储在主内存中,主内存共享的方式是线程各拷贝一份数据到工作内存,操作完成后刷新会主内存。

happens-before的八大原则:

1、程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写后面的操作

2、锁定原则:一个unlock操作先行发生于后面对同一个锁的lock操作

3、volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作

4、传递规则:如果操作a先行发生于操作b,而操作b又先行发生于操作c,则可以得出操作a先行发生于操作c

5、线程启动规则:thread对象的start()方法先行发生于此线程的每一个动作

6、线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断时间的发生

7、线程的终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过thread.join()方法结束,thread.isAlive()的返回值检测到线程已经终止执行。

8、对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始。

volatile变量为何立即可见?

当写一个volatile变量时,jmm会把该线程对应的工作内存中的共享变量值刷新到主内存中:

当读取一个volatile变量时,jmm会把该线程对应的工作内存置为失效。

volatile和synchronizd的区别

1、volatile本质是在告诉jvm当前变量在寄存器(工作内存)中,值是不确定的,需要从主存中读取,synchronizd则是锁定当前变量,只有当前线程可以访问该变量,其他线程别阻塞住知道该线程完成变量操作为止,

2、volatile仅能使用在变量级别,synchronizd则可以使用在变量,方法和类级别。

3、volatile仅能实现变量的修改可见性,不能保证原子性;而synchronizd则可以保证变量修改的可见性和原子性

4、volatile不会造成线程的阻塞,synchronizd可能会造成线程的阻塞

5、volatile标记的变量不会被编译器优化;synchronizd标记的变量可以被编译器优化

CAS(compare and swap)

一种高效实现线程安全性的方法

支持原子更新操作,适用于计数器,序列发生器等场景

属于乐观锁机制,号称lock-free

CAS操作失败时由开发者决定是继续尝试,还是执行别的操作

缺点:

若循环时间长,则开销很大(一直循环重试)

只能保证一个共享变量的原子操作

会存在ABA问题(加个版本号)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值