前言
上次说之后总结一下设计模式的面试题目,结果一晃时间过了这么久。看到别人的面经中提到了不少手写单例模式的题,所以来总结一下。
单例模式
单例模式指的是一个类仅有一个实例,并且提供这个类的全局访问点。
懒汉式,线程不安全
//这个是我在写网吧桌面端的时候用的单例模式,最基础最简单,但是是线程不安全的。
//当一个线程初始化到一半的时候,另一个线程访问,发现不是NULL就直接拿去用了。
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
懒汉式,线程安全
//相比之前的例子,多一个synchronized关键字,简单粗暴
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
饿汉式
//线程安全的方式,由于采用了static关键字所以在类加载的时候就产生了单例
//不存在多线程问题
public class Singleton{
private static Singleton instance = new Singleton();
private static Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
双重校验锁
//最经典的实现之一,线程安全
public class Singleton{
//采用volatile关键字确保一个线程初始化之后线程可见
private volatile static Singleton singleton;
private Singleton(){}
public static Singleton getSingleton(){
if(singleton == null){
//发现为空的时候使用synchronized关键字锁住这个类
synchronized(Singleton.class){
//锁住之后再次判断,因为这个时候有可能其他线程已经初始化好了
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
静态内部类
public class Singleton{
//静态内部类,实现更加简单,也不是在类加载的时候完成初始化
//等到外部调用getInstance()方法的时候才会显式地加载内部类
private static class SingletonHolder{
private static final Singleton INSTANCE = new Singleton();
}
private Singleton(){}
public static final Singeton getInstance(){
return SingletonHolder.INSTANCE;
}
}
枚举
//最强最简单,一定要记住,能够防止反射,不要带构造方法。
//线程安全懒汉式
public enum Singleton{
INSTANCE;
public void doSomething(){
...//业务逻辑
}
}
池化设计
听说师兄在面试的时候让他手写一个线程池,最后居然还被他写出来了,师兄竟然恐怖如斯。
这一块先欠着,明天再写,正好总结一下多线程的知识点。