设计模式:单例模式(singleton)

文章目录

  • 前言
  • 一、单例代码实现
    • 1.主程序代码
    • 2.静态常量(static final)
    • 3. 静态代码块(static code)
    • 4. 同步静态方法(synchronized static method)
    • 5. 双重检查(double check)
    • 6. 静态内部类(static inside class)
  • 总结

前言

单例模式:

  1. 是在整个软件生命周期中,值存在一个实例。使用单例模式可以提供系统性能。属于创建者
  2. 使用场景:频繁创建和销毁的对象、创建对象耗时过长或耗费资源过多的对象。

一、单例代码实现

1.主程序代码

代码如下(示例):

/**  * 保证整个软件系统中,对某个类智能存在一个对象实例  * 属于创建者模式  */publicclassSingletonClient{/**      * 1. 饿汉式(静态常量)      * 2. 饿汉式(静态代码块)      * 3. 懒汉式(线程安全、同步方法)      * 4. 双重检查      * 5. 静态内部类      * 6. 枚举      */publicstaticvoidmain(String[] args){staticFinal();staticCode();synchronizedMethod();synchronizedCode();staticInsideClass();enumInstance();}//枚举publicstaticvoidenumInstance(){SingletonEnum singleton1=SingletonEnum.INSTANCE;SingletonEnum singleton2=SingletonEnum.INSTANCE;System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}//饿汉式(静态常量)publicstaticvoidstaticFinal(){SingletonStaticFinal singleton1=SingletonStaticFinal.getInstance();SingletonStaticFinal singleton2=SingletonStaticFinal.getInstance();System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}//饿汉式(静态代码块)publicstaticvoidstaticCode(){SingletonStaticCode singleton1=SingletonStaticCode.getInstance();SingletonStaticCode singleton2=SingletonStaticCode.getInstance();System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}//懒汉式(同步方法)publicstaticvoidsynchronizedMethod(){SingletonSynchronizedMethod singleton1=SingletonSynchronizedMethod.getInstance();SingletonSynchronizedMethod singleton2=SingletonSynchronizedMethod.getInstance();System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}//懒汉式(同步代码块)publicstaticvoidsynchronizedCode(){SingletonSynchronizedCode singleton1=SingletonSynchronizedCode.getInstance();SingletonSynchronizedCode singleton2=SingletonSynchronizedCode.getInstance();System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}//懒汉式(静态内部类)publicstaticvoidstaticInsideClass(){SingletonStaticInsideClass singleton1=SingletonStaticInsideClass.getInstance();SingletonStaticInsideClass singleton2=SingletonStaticInsideClass.getInstance();System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}

2.静态常量(static final)

代码实现

/**  * 静态常量:单例  * instance:在类装载到方法区时,静态常量会自动创建。避免了多线程.  * 不好的地方是如果不使用,就会浪费内存。  */publicclassSingletonStaticFinal{privatestaticfinalSingletonStaticFinal  instance=newSingletonStaticFinal();/**      * 私有化是为了防止,外部类创建。      */privateSingletonStaticFinal(){}publicstaticSingletonStaticFinalgetInstance(){return instance;}}

3. 静态代码块(static code)

代码如下(示例):

/**  * 静态代码块:单例  * instance:在类装载到方法区时,会执行静态代码块。避免了多线程.  * 不好的地方是如果不使用,就会浪费内存。  */publicclassSingletonStaticCode{privatestaticSingletonStaticCode instance;//静态代码块static{         instance=newSingletonStaticCode();}/**      * 私有化是为了防止,外部类创建。      */privateSingletonStaticCode(){}publicstaticSingletonStaticCodegetInstance(){return instance;}}

4. 同步静态方法(synchronized static method)

代码如下(示例):

/**  * 同步静态方法:单例  * instance:在JAVA堆上创建,只有在使用的时候会创建。会出现多线程问题.  * 需要添加同步(synchronized)方法  * 只有在使用的时候创建,避免浪费内存。  * 出现问题:效率过低,每次调用都是同步  */publicclassSingletonSynchronizedMethod{privatestaticSingletonSynchronizedMethod instance;/**      * 私有化是为了防止,外部类创建。      */privateSingletonSynchronizedMethod(){}/**      * 每次执行,都是同步执行。导致效率过低      */publicsynchronizedstaticSingletonSynchronizedMethodgetInstance(){if(instance==null){             instance=newSingletonSynchronizedMethod();}return instance;}}

5. 双重检查(double check)

代码如下(示例):

/**  * 双重检查:单例  * instance:在JAVA堆上创建,只有在使用的时候会创建。会出现多线程问题.  * 需要添加同步(synchronized)方法  * 只有在使用的时候创建,避免浪费内存。  * 推荐使用  */publicclassSingletonSynchronizedCode{privatestaticvolatileSingletonSynchronizedCode instance;/**      * 私有化是为了防止,外部类创建。      */privateSingletonSynchronizedCode(){}//双重检查,publicstaticSingletonSynchronizedCodegetInstance(){if(instance==null){synchronized(SingletonStaticCode.class){//如果不检查,多线程情况下会创建多个实例if(instance==null){                     instance=newSingletonSynchronizedCode();}}}return instance;}}

6. 静态内部类(static inside class)

代码如下(示例):

/**  * 静态内部类:单例  * 推荐使用  */publicclassSingletonStaticInsideClass{privatestaticSingletonStaticInsideClass instance;static{         instance=newSingletonStaticInsideClass();}/**      * 私有化是为了防止,外部类创建。      */privateSingletonStaticInsideClass(){}privatestaticclassSignleton{privatestaticfinalSingletonStaticInsideClass INSTANCE=newSingletonStaticInsideClass();}publicstaticSingletonStaticInsideClassgetInstance(){//当静态方法调用是,才会加载内部静态类。//而内部静态类,在加载到方法区的时候会创建静态常量,避免多线程创建。returnSignleton.INSTANCE;}}

总结

推荐使用:

  1. 双重检查
  2. 静态内部类
  3. 枚举:还能有效防止反序列化。