Java锁机制
关键字:
sysnchronzied
CAS
CAS底层实现
对象的内存布局
markword细节
面试题:
1、请描述sysnchronized 和 reentrantlock的底层实现及重入的底层原理(百度、阿里)
sysnchronized 实现过程:
- java代码,sysnchronzied
- 字节码加了:monitorenter monitorexit
- 执行过程中自动升级
- lock comxchg
volatile 实现过程:
- 保证线程可见性
2、请描述锁的四种状态及升级过程(百度、阿里)
hotspot实现
无锁:new
偏向锁:大部分时候只是同一个线程运行(锁的状态偏向于这个线程)【无锁】【mark word中保留这条线程的信息】场景:大部分时间同一线程执行
自旋锁:有多个线程同时运行时,撤销偏向锁,升级为自旋锁【CAS】场景:线程锁的时间很短
重量级锁:由于某些线程锁的时间过长,自旋锁就会持续不断的自旋【CAS】,占用了大量cpu,升级为重量级锁,向操作系统申请资源。linux mutex , CPU从3级-0级系统调用,线程挂起,进入等待队列,等待操作系统的调度,然后再映射回用户空间。
线程进入一个队列【阻塞状态】,cpu通知锁释放时,队列里的进程才激活。场景:线程锁的时间较长
3、请谈一下AQS,为什么AQS的底层是CAS+volatile(百度)
4、请谈一下你对volatile的理解(美团、阿里)
5、volatile的可见性和禁止指令重排序是如何实现的(美团)
6、CAS是什么(美团)
compare and swap
- ABA问题(添加一个标志位布尔值 改过就是true 没改过是false)
- compare and exchange
lock cmpxchg 指令(比较的时候不允许修改)
cmpxchg 没有原子性(因为在比较E和当前值
时,当前值可能被改变 )
lock具有原子性,lock指令在执行后面指令的时候锁定一个北桥信号(不采用锁总线的方式)
-
synchronized关键字可以保证可见性和有序性却无法保证原子性。
-
而这个AtomicInteger的作用就是为了保证原子性。我们先看一个例子。
7、请描述一下对象的创建过程(美团、顺丰)
8、对象在内存中的内存布局(美团、顺丰)
工具:JOL(Java Object Layout )Java内存布局
<dependencies>
<!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>
</dependencies>
class pointer 被压缩(4字节)正常(8字节)
9、DCL单例为什么要加入volatile(美团)
10、解释一下锁的四种状态(顺丰)
11、Object o = new Object()在内存中占了多少字节(顺丰)
12、sysnchronized 和 reentrantlock的异同(顺丰)
13、聊一聊 as-if-serial 和 happens-before 语义的理解(京东)
14、你了解ThreadLocal吗?他如何解决内存泄漏问题(京东、阿里)
15、请描述一下锁的分类以及JDK的应用(阿里)
16、自旋一定比重量级锁效率高吗(阿里)
17、打开偏向锁是否效率一定会提升?为什么?
synchronized的底层实现:
- 锁升级过程
- C++代码及汇编
- 锁消除
- 锁粗化
并发编程三大特性
原子性
原子性:即一个或者多个操作作为一个整体,要么全部执行,要么都不执行,并且操作在执行过程中不会被线程调度机制打断;而且这种操作一旦开始,就一直运行到结束,中间不会有任何上下文切换(context switch)。
可见性
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看到修改的值。
有序性
有序性:即程序执行的顺序按照代码的先后顺序执行。
超线程
一个ALU对应多个PC|Registers所谓四核八线程
进程和线程有什么联系和区别?
定义:
-
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。
-
线程是进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),一个线程可以创建和撤销另一个线程;
2.进程和线程的关系:
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
(4)处理机分给线程,即真正在处理机上运行的是线程。
(5)线程是指进程内的一个执行单元,也是进程内的可调度实体。
3.线程与进程的区别:
进程:分配资源的基本单位
线程:线程执行的基本单位
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行。
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。
(4)系统开销:在创建或撤销进程的时候,由于系统都要为之分配和回收资源,导致系统的明显大于创建或撤销线程时的开销。但进程有独立的地址空间,进程崩溃后,在保护模式下不会对其他的进程产生影响,而线程只是一个进程中的不同的执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但是在进程切换时,耗费的资源较大,效率要差些
————————————————
版权声明:本文为CSDN博主「lm8580552lm」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lm8580552lm/java/article/details/76695206
cache line 缓存行对齐 伪共享
64字节
底层如何实现数据一致性
- MESI如果能解决,就使用MESI(缓存行对齐)
- 如果不能,锁总线
系统底层如何保证有序性
- 内存屏障 sfence mfence lfence等系统用语【fence篱笆,屏障】
- 锁总线
volatile如何解决指令重排序
-
volatile
-
ACC_VOLATILE(字节码里)
-
JVM的内存屏障
屏障两边的指令不可以重排!保证有序!
JSR内存屏障
-
hotspot实现
lock addl
指令重排序
乱序
cpu为了提高效率【乱序】
单例模式
DCL double check lock
DCL单例
DCL需不需要volatile修饰?