一、单例模式定义:
单例模式确保某个了某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在实际应用中,如打印机,线程池,日志等
二、单例模式特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式保证了全局对象的唯一性
实现单例模式的方法:
1 把构造函数设置为private 防止类被随意创建对象
2 提供public的方法返回单例对象
懒汉模式:
public class Singleton{
private static Singleton uniqueInstance ;
//创建单例对象的静态方法,延迟创建实例了其实
public static Singleton getInstance(){
if(null == uniqueInstance )
{
uniqueInstance = new Singleton();
}
return uniqueInstance ;
}
}
多线程情况下:
1 考虑线程安全时,创建单例的静态方法加上 synchronized ,
该方式运行效率却很低下,下一个线程想要获取对象,就必须等待上一个线程释放锁之后,才可以继续运行。
2 考虑多线程性能时,使用“急切”创建实例(饿汉模式)
private static Singleton uniqueInstance = new Singleton();
getInstance(){return uniqueInstance }
在类被加载时候就创建好了对象,增加了类的负担,如果是程序启动时候创建,就拖慢了程序的启动速度。
3 双重检查加锁,减少在getInstance()中使用同步 性能最好,避免整个方法被锁,只对需要锁的代码部分加锁
public class Singleton4 {
// 私有构造
private Singleton4() {}
private static Singleton4 single = null; // 双重检查 public static Singleton4 getInstance() { if (single == null) { synchronized (Singleton4.class) { if (single == null) { single = new Singleton4(); } } } return single; } }
4 静态内部类
public class Singleton{ private static class SingletonHolder{ public static Singleton INSTANCE = new Singleton(); } private Singleton(){} public static Singleton newInstance(){ return SingletonHolder.INSTANCE; } }
外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化,这样就不会占用内存。只有当newInstance第一次被调用时,才会初始化INSTANCE,第一次调用会加载SingletonHolder,这样不仅是线程安全的,也能保证单例的唯一性并且延迟了单例的实例化。
5从java1.5开始,可以使用枚举来创建单例,也是最佳方式
public enum hupObjectInstanceEnum
{
INSTANCE;
//属性
private EnumSingleton singleton;
//构造函数
private hupObjectEnum()
{
singleton = new EnumSingleton()
}
public EnumSingleton getInstance()
{
return singleton ;
}
}
原理:java枚举创建对象是线程安全的,枚举创建对象的过程本身就是单例子,所以可以hupObjectInstanceEnum.INSTANCE的方式调用。