java并发知识点梳理

tech2022-08-07  151

1. 进程与线程

进程可以视为程序的一个实例,大部分程序可以运行多个实例进程, 基本上相互独立。一个进程可以分为一个或多个线程进程拥有共享的资源,供其内部的线程共享。线程是最小的调度单位,比进程轻量,上下文切换成本比进程低。

2. 并发与并行

线程轮流使用CPU,成为并发,concurrent.多核cpu下,每个核都可以调度运行线程,这时候线程是并行的。

3. 一线大厂多线程面试题

请描述synchrnoized和reentrantlock的底层实现以及重入的底层原理(百度阿里)请描述锁的四种状态和升级过程(百度阿里)CAS的ABA问题如何解决(百度)请谈一下AQS,为什么AQS的底层是CAS+volatile(百度)请谈一下你对volatile的理解(美团阿里)volatile的可见性和禁止指令重排序是如何实现的(美团)CAS是什么(美团)请描述一下对象的创建过程(美团顺丰)对象在内存中的内存布局(美团顺丰)DCL单例为什么要加volatile(美团)Object o = new Object()在内存中占了多少字节(顺丰)聊聊你对as-if-serial和happens-before语义的理解(京东)你了解ThreadLocal吗,你知道ThreadLocal中如何解决内存泄漏问题吗(京东阿里)描述一下锁的分类以及在JDK中的应用(阿里)

4. CAS

compare and swap (比较和交换)在没有锁的情况下可以保证多个线程对一个值的更新。ABA问题:其它线程修改数次后最后值和原值相同解决ABA问题: 在值上加版本号,读取时连同版本号一起读取。CAS的底层实现 通过汇编指令 cmpxchg在多核cpu中指令为 lock cmpxchglock 指令在执行后面指令的时候锁定一个北桥信号 volatile底层实现于CAS一样,同样基于cmpxchg汇编指令JVM是一个标准基于JVM的实现有: hotspot(oracle实现)通常的JVM说法。OpenJDK(开源版本)J9(IBM版本)TaobaoVM(淘宝实现)

5. synchronized与volatile的实现

Object o = new Object() 在内存中占用16个字节java普通对象的结构: markword(对象头, 锁的信息记录在这里) 8个字节class pointer(类型指针,指明属于哪个类) 4个字节instance data(实例数据,成员变量存储的位置) 没有成员变量的话是0字节padding(对齐, 当对象的整体的字节数不能被8整除的时候,向上补齐)4个字节 markword: markword还记录GC信息锁的升级:无锁->偏向锁(偏向于最早到达的线程)->轻量级锁->重量级锁 升级为偏向锁时,当前线程的指针标记该资源。在有别的任意进程发生竞争时,偏向锁自动升级为轻量级锁, 首先撤销偏向锁状态,每个线程的线程栈生成LockRecord,谁的LockRecord 指针最先标记该资源,谁就抢到该轻量锁。抢的过程使用自旋的方式来抢。在自旋次数超过一定次数或者等待的线程超过一定数量的情况下(次数可自行配置), 锁升级为重量级锁。 锁消除 lock eliminate锁粗化 lock coarseningsynchronized底层实现 代码层:synchronized关键字字节码:通过monitorenter monitorexit监视器监视加锁代码执行过程中自动升级在更底层通过汇编lock cmpxchg指令来完成 在高竞争状态下使用synchronized效率更高在低竞争状态下使用CAS效率更高。volatile作用: 保证线程可见性禁止指令重排序(禁止乱序执行) 超线程: 一个ALU(逻辑运算器) 对应多个PC(指令寄存器)| Registers(寄存器)cache line(缓存行): cpu层级的数据一致性是以缓存行为单位的。每个缓存行大小64字节缓存行对齐 乱序执行:读指令的同时可以同时执行不影响的其它指令 而写的同时可以进行合并写 必须使用memery barrier做好指令排序,volatile的底层就是这么实现的 cpu底层如何保证数据一致性 MESI(缓存一致性协议)如果可用,就用MESI。MESI不可用,就锁总线 系统底层如何保证保证有序性 内存屏障 sfence mfence ifence锁总线 volatile如何解决指令重排序 volatileACC_VALOTILEJVM的内存屏障hotspot实现

6. 线程池

DCL(Double Check Lock):双重检查锁DCL单例 public class Mgr{ private static volatile Mgr INSTANCE; private Mgr(){ } public static Mgr getInstance(){ if(INSTANCE == null){ synchronized(Mgr.class){ if(INSTANCE == null){ try{ Thread.sleep(1); }catch(InteruptedException e){ e.printStackTrace(); } INSTANCE = new Mgr(); } } } return INSTANCE; } }
最新回复(0)