java 设计模式-单例

一、单例模式定义

单例模式确保某个了某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在实际应用中,如打印机,线程池,日志等

二、单例模式特点
  1、单例类只能有一个实例。
  2、单例类必须自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例。

单例模式保证了全局对象的唯一性

单例模式分两种

1  类加载时候就new好了这个对象,称为 "饿汉式"

2   在需要的时候,才调用公告方法创建对象,称为 "懒汉式"

 

实现单例模式的方法:

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 hupObjectInstanceEnum()
    {
        singleton = new EnumSingleton()
    }

    public EnumSingleton getInstance()
    {
        return singleton ;
    }
}

原理:java枚举创建对象是线程安全的,枚举创建对象的过程本身就是单例子,所以可以hupObjectInstanceEnum.INSTANCE的方式调用。


posted on 2019-01-22 09:56  鑫男  阅读(111)  评论(0编辑  收藏  举报

导航