标签:函数 懒汉式 业务 而且 需求 pre static 静态方法 关心
单例模式(Singleton),是一种常用的设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候,整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。
在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。事实上,这些应用都或多或少具有资源管理器的功能。例如,每台计算机可以有若干个打印机,但只能有一个 Printer Spooler(单例) ,以避免两个打印机同时打印一份文件。比如,每台计算机可以有若干通信端口,系统应当集中 (单例)管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。比如Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。
1、要求生产唯一序列号。
2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
确保一个类只有一个实例,并为整个系统提供一个全局访问点 (向整个系统提供一个获取这个类对象实例的公有方法,且只这个类能直接访问,这个对象只初始化一次,不需要重新实例化对象)。
1、单例类只能有一个实例(指向自己实例的私有静态引用)。
2、单例类必须自己创建自己的唯一实例(私有的构造方法)。
3、单例类必须给所有其他对象提供这一实例(以自己实例为返回值的静态的公有方法)。
1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例
2、避免对资源的多重占用
1、有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
饿汉式(最普遍常用的一种方式,缺点是加载这个类时就会初始化这个实例对象)
public class Singleton {
//创建这个类的一个对象(静态私有的全局对象),加载时初始化一次
private static Singleton singleton = new Singleton ();
//让构造函数为 private,这样该类就不会被外部类实例化
private Singleton(){}
//获取唯一可用的对象的方法
public static Singleton getSingleton(){
return singleton ;
}
}
懒汉式 :第一次调用才初始化,避免内存浪费(解决饿汉式的不足)
//方法1,存在线程安全
public class Singleton{
//定义这个类的对象,不进行初始化
private static Singleton singleton;
//提供私有的构造方法,防止这个类被外部类初始化
private Singleton(){}
//提供唯一获取这个类对象的公共静态方法
public static Singleton getSingleton(){
//如果这个对象等于null则进行初始化
if(singleton==null){
singleton=new Singleton();
}
return singleton;
}
}
//方法2,给这个唯一的方法进行加锁解决线程安全,但是效率变低
public class Singleton{
//定义这个类的对象,不进行初始化
private static Singleton singleton;
//提供私有的构造方法,防止这个类被外部类初始化
private Singleton(){}
//提供唯一获取这个类对象的公共静态方法
public static synchronized Singleton getSingleton(){
//如果这个对象等于null则进行初始化
if(singleton==null){
singleton=new Singleton();
}
return singleton;
}
}
//方法3, 双重判断解决效率变低问题,完美解决上面2种方式的不足但是实现难度较复杂
public class Singleton{
//定义这个类的对象,不进行初始化
private static Singleton singleton;
//提供私有的构造方法,防止这个类被外部类初始化
private Singleton(){}
//提供唯一获取这个类对象的公共静态方法
public static Singleton getSingleton(){
//如果这个对象等于null则进行初始化
if(singleton==null){
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
return singleton;
}
}
静态内部类方式(也解决上面的缺点,同时更简单的方式)
只有通过显式调用getSingleton方法时,才会进行加载 SingletonHolder 类,初始化Singleton 对象
public class Singleton {
//私有静态内部类进行该类的创建和初始化
private static class SingletonHolder {
private static final Singleton singleton = new Singleton();
}
//私有构造器
private Singleton (){}
//公共的方法
public static final Singleton getSingleton() {
return SingletonHolder.singleton ;
}
}
枚举方式
描述:这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。不过,由于 JDK1.5 之后才加入 enum 特性,用这种方式写不免让人感觉生疏,在实际工作中,也很少用。
public enum Singleton {
//全局属性 要调用的话直接Singleton.INSTANCE就行
INSTANCE;
//业务逻辑
public void whateverMethod() {
}
}
一般情况下,建议使用饿汉式和懒汉式第二种方式。只有在要明确实现 lazy loading 效果时,才会使用静态内部类方式。如果涉及到反序列化创建对象时,可以尝试使用最后枚举方式。如果有其他特殊的需求,可以考虑使用第 懒汉式第三种方式。
标签:函数 懒汉式 业务 而且 需求 pre static 静态方法 关心
原文地址:https://www.cnblogs.com/panDty/p/12512557.html