核心作用:
保证一个类只有一个实例,并提供一个访问该实例的全局访问点
单例的三大要点:
线程安全
延迟加载
序列化与反序列化安全
常见场景:
1. 读取配置文件
2. 网站计数器
3. 日志应用
4. 连接池
5. spring中每个bean默认就是单例
6. servlet
常见五中实现方式:
懒汉式:
线程安全,调用效率高,不能延迟加载
饿汉式:
线程安全,调用效率不高,可以延迟加载
双重检测锁式:
非线程安全,偶尔会出现问题,不建议使用
静态内部类式:
线程安全,调用效率高,可以延迟加载
枚举单列:
线程安全,调用效率高,不能延迟加载
懒汉式
/**
* 懒汉式单例模式
* 特点:线程安全,调用效率不高,可以延迟加载
* @author Roger
*/
public class SingletonDemo3 {
// 类初始化时,不初始化,延迟加载
private static SingletonDemo3 instance = null;
private SingletonDemo3(){ // 私有构造器
}
// 方法同步,调用效率低
public static synchronized SingletonDemo3 getInstance(){
if(instance == null){
instance = new SingletonDemo3();
}
return instance;
}
}
饿汉式
/**
* 饿汉式单例模式
* 特点:线程安全,调用效率高,不能延迟加载
* @author Roger
*/
public class SingletonDemo1 {
// 类初始化时,立即加载,天然的线程安全
private static SingletonDemo1 instance = new SingletonDemo1();
private SingletonDemo1(){ // 私有构造器
}
public static SingletonDemo1 getInstance(){
return instance;
}
}
枚举
/**
* 枚举 单例模式
* 特点:线程安全,调用效率高,不能延迟加载,避免反射和反序列号漏洞
* @author Roger
*/
public enum SingletonDemo5 {
/**
* 这个枚举原始,本身就是单例模式
*/
INSTANCE;
// 添加自己需要的操作
public void singletonOperation(){
System.out.println("这是一个枚举单列");
}
}
静态内部类法
/**
* 静态内部类法 单例模式
* 特点:线程安全,调用效率高,可以延迟加载
* @author Roger
*/
public class SingletonDemo4 {
// 初始化SingletonDemo4类时不会初始化该内部类,实现延迟加载
private static class SingletonInstance{
private static SingletonDemo4 instance = new SingletonDemo4();
}
private SingletonDemo4(){ // 私有构造器
}
public static SingletonDemo4 getInstance(){
return SingletonInstance.instance;
}
}
双重检测锁式
/**
* 双重检查锁单例模式
* 特点:非线程安全,偶尔会出现问题,不建议使用
* @author Roger
*/
public class SingletonDemo2 {
private static volatile SingletonDemo2 singleton = null;
private SingletonDemo2(){}
public static SingletonDemo2 getSingleton(){
if(singleton == null){
synchronized (SingletonDemo2.class){
if(singleton == null){
singleton = new SingletonDemo2();
}
}
}
return singleton;
}
}
转载于:https://blog.51cto.com/10960988/1791012