本节内容不过是对尚硅谷面试题第二季(多线程篇)的补充罢了,一切都是围绕着尚硅谷面试题第二季(多线程篇)来
文章目录
- 1、懒汉式为什么要加volatile关键字?
- 1.说说sychronized的理解
- 1.说说自己是怎么使用 synchronized 关键字
- 1.构造方法可以使用 synchronized 关键字修饰么?
- 1.说说synchronized的实现原理
- 4.Java原子类AtomicInteger实现原理
- 9.了解过什么是“伪共享”吗?
- 11.如何避免“伪共享”?
- 32.为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法?
- 13.什么是悲观锁?什么是乐观锁?
- 7.说一下Java中Unsafe类
- 22.什么是AQS?
- 22.AQS的底层原理
- 22.AQS 底层使用的模板方法模式
- 31.sleep() 方法和 wait() 方法的区别和共同点?
- 33.什么是线程安全问题?如何解决?
- 34.什么是活锁?
- 35.什么是线程的饥饿问题?如何解决?
- 36.什么是线程的阻塞问题?如何解决?
- 41.Java中如何获取到线程dump文件
- 10.什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing)?
- 42.Java中用到的线程调度算法是什么?
- 43.Thread.sleep(0)的作用是什么?
- 47.同步方法和同步块,哪个是更好的选择?
- 48.为什么要弄一个 CPU 高速缓存呢?
- 49.ThreadLocal 了解么?
- 5.ThreadLocal 原理讲一下
- 6.ThreadLocal 内存泄露问题了解不?
- 7.执行 execute()方法和 submit()方法的区别是什么呢?
- 8.介绍一下 Atomic 原子类
- 8.JUC 包中的原子类是哪 4 类?
- 线程池如何知道一个线程的任务已经执行完成?
- 讲一下 wait 和 notify 这个为什么要在synchronized 代码块中?
- 什么是守护线程,它有什么特点
1、懒汉式为什么要加volatile关键字?
public class Singleton5 {
private Singleton5(){
}
/**
* 为什么要用volatile修饰?
* 因为下面的new Singleton5()在底层是分三步执行的,其中第二步是初始化对象,第三步是设置instance指向的内存地址,
* 第二步和第三步没有先后顺序,一旦先执行第三步,后执行第二步,就危险了,怎么危险呢?
* 就是执行完第三步设置instance指向的内存地址后突然来了个线程,这个线程执行if(instance == null){时得到instance不为空,就把这个instance返回了,但是其实这个instance第二步初始化对象还没有执行完呢
* 而被volatile修饰的遍历会严格按照三步顺序执行
*/
private volatile static Singleton5 instance;
public static Singleton5 getInstance(){
//提高效率
if(instance == null){
//增加同步锁
synchronized (Singleton5.class){
//双端验证(为什么使用双端校验?查看“尚硅谷面试题第二季”)
if(instance == null){
//这个new Singleton5()其实分三步执行:①分配对象内存空间②初始化对象③设置instance指向刚分配的内存地址,此时instance!=null
instance = new Singleton5();
}
}
}
return instance;
}
}
1.说说sychronized的理解
synchronized
关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行
。
另外,在 Java 早期版本中,synchronized 属于 重量级锁
,效率低下。
为什么呢?
因为监视器锁(monitor)是依赖于底层的操作系统的,如果要挂起或者唤醒一个线程,都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换到内核态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高。
庆幸的是在 Java 6 之后 Java 官方对从 JVM 层面对 synchronized 较大优化,所以现在的 synchronized 锁效率也优化得很不错了。JDK1.6 对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。
所以,你会发现目前的话,不论是各种开源框架还是 JDK 源码都大量使用了 synchronized
关键字。
1.说说自己是怎么使用 synchronized 关键字
修饰代码块、修饰静态方法、修饰实例方法
1.构造方法可以使用 synchronized 关键字修饰么?
先说结论:构造方法不能使用 synchronized 关键字修饰。
构造方法本身就属于线程安全的,不存在同步的构造方法一说。
1.说说synchronized的实现原理
synchronized 同步语句块
的实现使用的是 monitorenter
和 monitorexit
指令,其中 monitorenter 指令指向同步代码块的开始位置,monitorexit 指令则指明同步代码块的结束位置。
当执行 monitorenter
指令时,线程试图获取锁也就是获取monitor 的持有权
。(在 Java 中,每个对象都隐式包含一个monitor对象监视器)
在执行 monitorexit
指令后,线程试图释放锁也就是释放monitor 的持有权
。
①提问:那线程是如何获取对象监视器 monitor 的持有权的?
在执行monit