1.定义
一个类有且只有一个实例,并且自行实例化向整个系统提供。
2.特点
A.单例类只能有一个实例;
B.单例类必须自己实例化;
C.单例类必须向其他对象提供实例。
简单的说就是,保证系统中的单例类必须只能有一个实例。在日常应用中,通常是将资源管理器设计成单例类,比如线程池、日志对象、打印机、驱动程序等,它们保证了系统资源分配一致性,不会紊乱。
3.实现方式
将单例类实现方式按实例化的时间(类加载时、第一次调用时),通常分成懒汉式单例、饿汉式单例和登记式单例,懒汉式单例是在类第一次使用时对垒进行实例化,饿汉式单例类是在类加载时实例化,登记式单例采用工厂模式的方法,通过类名获取。
3.1.懒汉式单例类
懒汉式单例类在类第一次调用时进行实例化,通常的实现方式,如下:
public class Singleton()
{
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance()
{
if(null == instance)
{
instance = new Singleton();
}
return instance;
}
}
改方式是线程不安全的要保证线程安全有三种方法实现:
A.对getInstance方法加同步(sychronized)
public static synchronized Singleton(){......}
B.双重检查锁定(对Singleton类进行锁定)
public static Singleton getInstance()
{
if(null == instance)
{
synchronized(Singleton.class)
{
if(null == instance)
{
instance = new Singleton();
}
}
}
return instance;
}
C.静态内部类方式
public class Singleton()
{
private static class LazyHolder()
{
public final static Singleton INSTANCE = new Singleton();
}
private Singleton(){}
public static Singleton getInstance()
{
return LazyHolder.INSTANCE;
}
}
静态内部类的方式保证了线程安全还避免了性能问题。
3.2.饿汉式单例类
饿汉式单例类在类加载时就实例化,因为它在类的创建时就已经实例化一个对象,以后不再改变,因此是天生线程安全的。
public class Singleton()
{
private final static instance = new Singleton();
private Singleton(){}
public static Singleton getInstance()
{
return instance;
}
}
3.3.登记式单例类
类似Spring的方法,将类名和类实例添加到一个map中,要用的时候,直接在map中通过类名取,类似工厂模式,实现代码省略。