volatile、CAS、锁机制

1.volatile(可见性和指定重排序)

  1. JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。JVM是整个计算机虚拟模型,所以JMM是隶属于JVM的。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(Main Memory)中,每个线程都有一个私有的本地内存(Local Memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存、写缓冲区、寄存器以及其他的硬件和编译器优化。
    在这里插入图片描述
  2. volatile 修饰后的内容 线程在通过总线的时候 通知总线(监听器)我修改了 volatile修饰的这个变量,那么总线会通知其他线程,缓存中的volatile修饰的变量的内容变了,你们缓存中的对象失效了,然后其他线程在通过总线获取最新的对象内容。
  3. 缓存一致性协议(MESI)
    MESI分别代表缓存行数据所处的四种状态,通过对这四种状态的切换,来达到对缓存数据进行管理的目的。
    在这里插入图片描述

1. volatile是如何处理指令冲排序的?

  1. 什么是指令冲排序?指令冲排序是指cpu在执行代码的时候不会按照指定顺序执行,而是有可能先执行第三行,在执行第二行,这种情况就是指令冲排序。
  2. 什么是DCL 单例?DCL是指 double chack lock,指双重判断锁
public class E {
    public static volatile E Instance;

    private E(){}

    public static E getInstance(){
        if(Instance == null){
            synchronized (E.class){
                if (Instance == null){
                    Instance = new E();
                }
            }
        }
        return Instance;
    }

}

  1. 什么是半初始化?我们new 一个类,这个指令计算机会执行5个指令:new(申请内存)、dup、invokespecial(初始化参数)、astore(引用只指向内存)、return。半初始化是指 3 4 指令 可能优先执行了4 没有执行3,就被其他线程那去使用了。
  2. DCL单例是否需要加Volatile?需要 为了防止类半初始化问题。
  3. volatile为什么能实现可见性,和指令重排?因为voletile会增加内存屏障,内存屏障是加增加 lock,执行汇编指令 lock addl , lock作用时独占总线,我修改了内容会通知其他线程改内容失效,其他线程自动更新,并且还会使加锁位置前后代码不能穿插执行。

2. CAS

  1. CAS 三个值 第一个 预期值 A ,当前值 B ,修改值C,当A = B 把 B修改成C ,怎么实现了 汇编语言lock cmpxchg , cpu 线程 锁总线。
  2. A-B-A问题 现在有三个线程 一个 i = 0, A 修改了 i的值 改成 1,B把1 拿走 改成了 0 C又把 0 改成了 这种情况下 我们是不知道 i的值 究竟i究竟有没有被修改过。 解决办法 1. 加版本号 2.邮戳
  3. CAS和sychronized性能谁更高? 分场景,看线程个数和该操作具体时间负责度
    1. 因为CAS自选消耗CPU性能如果线程过多CPU性能消耗严重,而sychronized是在操作系统排队。
  4. 如何保证原子性?lock comxchg cpu 线程 锁总线。

3.synchronized

  1. 重量级锁 jvm发起线程、和锁 都交由os(管理),os处理锁争抢等,处理结束反馈给jvm,jvm反馈给程序。
  2. 轻量级 jvm自己管理,不交由os管理,CAS自旋竞争。
  3. 偏向锁 是同步标签,因为大多数同步方法不需要抢锁,所以偏向锁只是记录进入的线程的id,A线程查看id是否是自己,如果不是撤销id,
    B线程要获取资源,失败后 偏向锁升级成为 轻量锁(自旋锁)。
  4. 锁升级
    1. 偏向锁出现第二个竞争资源的线程升级为轻量锁,轻量锁自旋过程消耗cpc资源过多,升级重量锁。
    2. 当GC访问该资源时,触发锁降级机制。
  5. 核心
    1. wait set 这里存放执行了 wait的线程
    2. contention list 竞争队列,所有请求锁的线程都放在这里。
    3. Entry list 存放有资格竞争所的候选者,以你各位contention list 尾部位置竞争激烈才尊放在entry list中
    4. Ondeck 任意时刻,只能有一个线程竞争锁,他来自contention list的尾部
    5. owner 获取到锁的对象
    6. !owner 释放锁的独享

4.类创建内存对象

  1. markwork
  2. Class pointer
  3. instance data
  4. 补全数据
  5. 1 + 2 全称 Object head , 2 指向类信息 如创建 object 就是 object.class ,3部分存放 变量信息 4部分为 补全位置 如果前三项内存空间相加 不能被8 整除 就用第4部分补全, 1部分内存放最重要信息是 头部的锁
    在这里插入图片描述

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值