1 OOM的认识

java.lang.StackOverflowError
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: GC overhead limit exceeded
java.lang.OutOfMemoryError: Direct buffer memory
java.lang.OutOfMemoryError: Metaspace
java.lang.OutOfMemoryError: unable to create new native thread
java.lang.OutOfMemoryError: Requested array size exceeds VM limit

2 JUC多线程及高并发

java.util.concurrent
volatile是什么?
java虚拟机提供的轻量级的同步机制

JVM(java虚拟机):可见性,原子性(i++在多线程下是非线程安全的)

volatile三特性:
1.保证可见性(一个线程改变主内存中的共享变量副本,再写回主内存,及时通知其他线程共享变量改变)
2.不保证原子性(不可分割,完整性:某个线程正在做某个具体业务时,中间不可以被加塞或者分隔。需要整体完整 要么成功 要么同时失败)
解决原子性:加sync,使用juc下的AtomicInteger
3.禁止指令重排
java面试题(高级一点的)
java面试题(高级一点的)

3 单例模式在多线程可能存在安全问题

单例模式
java面试题(高级一点的)
多线程下
java面试题(高级一点的)
在getInstance方法前面加synchronized,尽量不要用哦,把整个都加锁了。

DCL(Double Check Lock双端检索机制)
java面试题(高级一点的)
DCL不一定线程安全,存在指令重排,加入volatile禁止指令重排。
原因在于某一个线程执行到第一次检测,读取到的instance不为null时,instance的引用对象可能没有完成初始化。instance = new SingletonDemo(); 可以分为以下3步完成(伪代码)
memory = allocate(); //1. 分配对象内存空间
instance(memory); //2.初始化对 象
instance = memory; //3. 设置instance指向刚分配的内存地址,此时instance! =null
步骤2和步骤3不存在数据依赖关系,而且无论重排前还是重排后程序的执行结果在单线程中并没有改变,因此这种重排优化是允许的。
memory = allocate(); //1.分配对象内存空间
instance = memory; //3.设置instance指向刚分配的内存地址,此时instance! =null,但是对象还没有初始化完成!
instance(memory); //2.初始化对象
但是指令重排只会保证串行语义的执行的一致性(单线程),但并不会关心多线程间的语义一致性。
所以当一条线程访问instance不为null 时,由于instance实例未必已初始化完成,也就造成了线程安全问题。
java面试题(高级一点的)

4 CAS

CAS:比较并交换

以上资料来源尚硅谷面试视频。

相关文章:

  • 2021-12-31
  • 2021-12-07
  • 2021-07-24
  • 2021-12-16
  • 2021-12-16
  • 2021-12-05
猜你喜欢
  • 2022-12-23
  • 2021-12-05
  • 2021-12-06
  • 2021-12-16
  • 2021-12-06
  • 2021-12-03
相关资源
相似解决方案