课程名称:笑傲Java面试 剖析大厂高频面试真题 秒变offer收割机
课程章节:第5章 并发提高篇
主讲老师:求老仙
课程内容:
第5章 并发提高篇
课程收获:
一般面试官问,怎么弄最好,一般是要求说出你的思考过程,说出几个方案,然后做比较。
问题1)并发编程三要素?
原子性:要么做要么不做
**有序性:任何时刻,各个线程看到的内容是一致的。**体现在一致性上,所有线程在同一时刻,看同一个变量,应该是一致的。(有序就是每个线程有序执行)
可见性:一个线程操作了内存,对另外一个线程可见
-
一致性分三类,强一致性,若一致性,没有一致性
-
强一致性只有单线程才能做到
-
弱一致性是通过程序实现的》通过
问题2)为什么会产生不一致?
- Cpu内存不一致导致多线程看到的内存不一致:
主要是原因是cpu有多级缓存,cpu1读取了A,cpu2也读取A,
Cpu1更改了A值,cpu2的缓存没有及时的更新A的值。
2, 指令重排序,也会导致不一致。
指令重排:定义一个变量分成3步骤:分配内存,初始化,指针指向存储空间
问题3)内存不一致的例子?
// 一个线程设置值,一个线程读取不到值
static int a = 0;
public static void main(String[] args) {
Runnable th01= ()->{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
a =1000;
System.out.println(“end thread01”);
};
Runnable th02= ()->{
while (a < 10){
// 什么也不做
}
System.out.println(“end thread02”);
};
Thread thread01 = new Thread(th01);
Thread thread02 = new Thread(th02);
thread01.start();
thread02.start();
}
问题4)volatile的作用?
-
防止重排序
-
内存可见,一个线程改变了变量值,另外一个线程读取到最新的值
问题5)synchronize的锁?
设计目的、各个锁的场景
如何进入下一个锁,偏向锁的释放锁
锁的原理
synchronize的偏向锁和轻量级锁
偏向锁(适合单线程,cas只需要比较Thread id)-》轻量级锁(自旋锁,适合多线程,执行时间短)-》重量级锁(互斥锁,mutex)
设计偏向锁的目的:只有一个线程使用资源,就不需要获取重量级锁。
在没有实际竞争的情况下,如果不仅仅没有实际竞争,自始至终,使用锁的线程都只有一个,那么,维护轻量级锁都是浪费的。偏向锁的目标是,减少无竞争且只有一个线程使用锁的情况下,使用轻量级锁产生的性能消耗。轻量级锁每次申请、释放锁都至少需要一次CAS,但偏向锁只有初始化时需要一次CAS。