单例顾名思义就是只会有单个实例。
这里介绍四种单例的写法:
1、饿汉式(推荐,因为简单实用)
/**
* 单例模式 饿汉 简单实用
* @author wangkai
* @date 2020-06-24 13:02
*/
public class SingleTon {
private static SingleTon INSTANCE = new SingleTon();
private SingleTon(){}
public static SingleTon getInstance(){
return INSTANCE;
}
}
2、枚举方式(就单例而讲,完美,但不见得单例都要搞成枚举)
/**
* 枚举方式
* 可以解决线程同步问题,也可以防止反序列化(因为枚举没有构造方法)
* @author
* @date 2020-11-19 17:27
*/
public enum SingleTon3 {
INSTANCE;
public void m(){}
public static void main(String[] args) {
SingleTon3.INSTANCE.m();
}
}
3、DCL单例(双重检查+加锁)
/**
* 双重检查
* 需要加下volatile,防止JIN(java-in-time)的时候指令重排造成的问题
* @author
* @date 2020-11-19 17:09
*/
public class SingleTon2 {
private static volatile SingleTon2 INSTANCE;
private SingleTon2(){}
public static SingleTon2 getInstance(){
if(INSTANCE == null){
synchronized (SingleTon2.class){
if(INSTANCE == null){
INSTANCE = new SingleTon2();
}
}
}
return INSTANCE;
}
}
4、静态内部类
/**
* 静态内部类的方式
* 是由jvm控制线程安全。jvm加载一个类只会加载一次,所以其内部静态类也会被加载一次。
* @author
* @date 2020-11-19 17:34
*/
public class SingleTon4 {
private SingleTon4(){}
private static class MyHolder{
private final static SingleTon4 INSTANCE = new SingleTon4();
}
public static SingleTon4 getInstance(){
return MyHolder.INSTANCE;
}
}