「扫码关注我,面试、各种技术(mysql、zookeeper、微服务、redis、jvm)持续更新中~」
单例模式:顾名思义,就是单个实例。目的:确保一个类只有一个实例存在,也就是说在整个系统中,如果你希望某个类只能出现一个实例,那么单例模式就派上用场了。下面我们来讨论如何实现单例模式。
1)饿汉式
/**
* 饿汉式
* 优点:JVM保证线程安全,实现简单
* 缺点:类加载就完成初始化,如果不被使用,造成资源浪费
*/
public class Example1 {
//构造方法私有
private Example1(){}
private final static Example1 INSTANCE = new Example1();
public static Example1 getInstance(){return INSTANCE;}
}
2)懒汉式
/**
* 懒汉式
* 优点:使用的时候再加载
* 缺点:需要自己保证线程安全
*/
public class Example2 {
//构造方法私有
private Example2(){}
//volatile防止指令重排序
private volatile static Example2 INSTANCE;
//双重校验保证线程安全
public static Example2 getInstance(){
if(INSTANCE == null){
synchronized (Example2.class){
if(INSTANCE == null){
INSTANCE = new Example2();
}
}
}
return INSTANCE;
}
}
3)静态内部类
/**
* 静态内部类
* 优点:JVM保证线程安全,实现简单,使用时加载
*/
public class Example3 {
//构造方法私有
private Example3(){}
//内部类
private static class InnerClass{
private final static Example3 INSTANCE = new Example3();
}
public static Example3 getInstance(){
return InnerClass.INSTANCE;
}
}
4)枚举类实现
/**
* 利用枚举实现
* 不仅可以保证线程安全,还可以防止反序列化
*/
public enum Example4 {
INSTANCE;
}
5)交给Spring实现
/**
* Spring实现:默认bean单例
*/
@Configuration
public class Example5 {
@Bean
public Example5 getInstance(){
return new Example5();
}
}