HashMap扩容机制:不指定初始值则初始容量16,每次扩容2n。指定初始值,会扩容成初始值2的幂次方
Hashtable扩容机制:不指定初始值则初始容量11,每次扩容2n+1。指定初始值,则使用初始值
volatile: 关键字除了防⽌ JVM 的指令重排 ,还有⼀个重要的作⽤就是保证变量的可⻅性,解决内存缓存不一致的问题。被该关键字修饰的变量每次使用都需要到主存获取最新的值
ThreadLocal:使线程拥有专属的本地变量确保线程安全,避免引起线程竞争
ThreadLocal 内存泄露问题:底层是类似Map的ThreadLocalMap数据结构,key是弱引用,value是强引用,垃圾回收(GC)的时候,当key没有被外部强引用的时候会被回收产生key为null的Entry,而留下value值永远无法被回收。而在ThreadLocalMap中,每次调用get(),set(),remove()它会自动清除key为null的记录
实现 Runnable 接⼝和 Callable 接⼝的区别:
前者异常不会返回结果和抛出异常,后者会
执⾏ execute()⽅法和 submit()⽅法的区别是什么呢?
前者用于提交不需要返回值的任务无法判断线程池是执行与否,后者用于提交需要返回值的任务,执行成功会返回一个future对象(通过get方法可以获取返回值)。
单例模式(双重检验锁实现对象单例,线程安全)
public class Singleton(){
private volatile static Singleton uniqueInstance;
private Singleton(){};
public static Singleton getUniqueinstance(){
if(uniqueinstance == null){
synchronized(Singleton.class){
if(uniqueinstance==null){
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
懒汉模式(加synchronized锁):
public class Singleton(){
private static Singleton single = null;
private singleton(){};
private static synchronized Singleton getInstance(){
if(single == null){
single = new Singleton();
}
return single;
}
}
原理:需要使用的时候才实例化这个单例(调用getInstance方法)
饿汉模式(线程安全):
public class Singleton(){
private static Singleton single = new Singleton();
private Singleton(){};
private static Singleton getInstance(){
return single;
}
}
原理:类的初始化过程中,类同时已经被实例化出来
单例模式下的无参构造器必须是Private
如何破坏单例模式? —–> 反射
AQS原理(⽤来构建锁和同步器的框架):
如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的⼯作线
程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占⽤,那么就需要⼀套线程阻塞
等待以及被唤醒时锁分配的机制,这个机制 AQS 是⽤ CLH 队列锁实现的,即将暂时获取不到锁
的线程加⼊到队列中。
**个人理解:**类似于当有空余的资源可以投入到一个项目当中,这个项目被列为可行项目,项目所需要的资金会被锁定,如果资源暂时被占用,我们就通过约定的方式来等待和通知资源可以分配
常见的设计模式?
- 工厂设计模式
- 单例设计模式:在内存中保证对象的实例只有一个
- 代理设计模式:Spring框架中Aop就是通过代理模式实现
- 适配器设计模式:SpringMVC中contoller就使用到了适配器模式
- 装饰者设计模式:不改变原有对象结构的基础上,增加新的功能
- 状态模式:允许对象在内部状态改变的时候改变它的行为,对象看起来好像改变了它的类