设计模式23之一一单例模式5

Posted PoeticalJustice

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式23之一一单例模式5相关的知识,希望对你有一定的参考价值。

package com.gof23.singleton;
/**
 * 单例模式
 *  核心作用:保证一个类只要一个对象,提供一个方法访问这个对象。
 *  常见应用场景:
 *  windows里面的任务管理器就是个单例 回收站也是
 *  项目中的配置文件
 *  网站的计数器
 *  程序应用的日志
 *  数据库的连接池
 *  操作系统的文件系统
 *  Servlet中的Application对象也是单例
 *  servlet编程中,每个serv也是单例
 *  在Spring中每个Bean默认也是单例的 这么做的原因是方便Spring容器管理
 *  springMVC框架/struts框架中,控制器的对象也是单例
 *  
 *  优点
 *  减少系统性能开销
 *  优化共享资源访问
 *  
 *  常见5种单例模式的实现方式:
 *   主要
 *       懒汉式: 线程安全,效率不高、但可以延时加载。
 *       饿汉式:线程不安全,效率高。但是,不能延时加载、
 *   其他
 *       双重检测锁式 :由于JVM底层内部模型的原因,偶尔出问题,不建议使用。
 *       静态内部类式: 线程安全,效率高。还可 延时加载。
 *       枚举单例 :         线程安全效率高 ,但不能延时加载。
 */
public class SingleTonTest {
     public static void main(String[] args) {
        HungrySingleton s1 = HungrySingleton.getInstance();
        LazySingleton   s2 = LazySingleton.getInstance();
        DoubleCheckLock s3 = DoubleCheckLock.getInstance();
        StaticInnerClassesDemo s4 = StaticInnerClassesDemo.getInstance();
        EnumDemo s5 = EnumDemo.INSTANCE;
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
        System.out.println(s4);
        System.out.println(s5);
    }

}
com.gof23.singleton.HungrySingleton@3fbefab0
com.gof23.singleton.LazySingleton@133c5982
com.gof23.singleton.DoubleCheckLock@5f186fab
com.gof23.singleton.StaticInnerClassesDemo@3d4b7453
INSTANCE

饿汉模式

package com.gof23.singleton;
/**
 * 饿汗模式
 * 饿汉式:线程不安全,效率高。但是,不能延时加载。
 * 调用方法
 * 直接返回一个对象
 * @author Administrator
 *
 */
public class HungrySingleton {
    //静态属性 从属于类 这个属性 指向一个对象。
    //加载类时,天然的线程是安全的。  类初始化式立即加载(没有延时加载,资源浪费。)
    private static final HungrySingleton hungrySingleton=new HungrySingleton();//提供一个属性 类初始化式立即加载
    
    private HungrySingleton(){};//把构造器私有,别人访问不了。
    
    //提供一个公开的方法         由于加载类时,天然的线程是安全的。
    // 所以不加同步                      synchronized  效率更高
    public static /*synchronized*/ HungrySingleton getInstance(){
        return hungrySingleton;
    }
    
}

懒汉模式

package com.gof23.singleton;
/**
 * 懒单例模式
 *    先判断 再创建
 *    懒汉式: 线程安全,效率不高、但可以延时加载。
 * @author Administrator
 *
 */
public class LazySingleton {
    //类加载时 不初始化这个对象 (延时加载)真正用时再初始化对象   加载类是天然线程安全
    private static LazySingleton lazySingleton=null;
    
    private LazySingleton(){};//私有构造器
    
    //延时加载 懒加载 资源利用效率高 但每次调用 getInstanc()方法都要同步synchronized(避免并发高的时候多个线程创建多个对象) 并发效率比较低。
    public synchronized static LazySingleton getInstance(){
        //第一加载 判断 为空 创建对象  那么 第二次判断不为空 则立即返回对象
        if(lazySingleton==null){
            
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
}

双重检测锁模式(不建议使用)

package com.gof23.singleton;
/**
 * 双重检测锁式 :由于JVM底层内部模型的原因,偶尔出问题,不建议使用。
 * 
 * 综合了懒汉式和饿汉式的优点
 * 但是由于底层JVM模式 不支持和编译器优化不好 所以不建议使用
 * 
 * 第一次的时候 同步 之后 直接返回对象
 * @author Administrator
 *
 */

@Deprecated
public class DoubleCheckLock {
    public static DoubleCheckLock doubleCheckLock=null;
    public static DoubleCheckLock getInstance(){
        if(doubleCheckLock==null){
            DoubleCheckLock sc;
            synchronized(DoubleCheckLock.class){
                sc=doubleCheckLock;
                if(sc==null){
                    synchronized(DoubleCheckLock.class){
                        if(sc==null){
                            sc=new DoubleCheckLock();
                        }
                    }
                    doubleCheckLock = sc ;
                }
            }
        }
        return doubleCheckLock;
    }
}

静态内部类模式

package com.gof23.singleton;
/**
 * 静态内部类式: 线程安全,效率高。还可 延时加载。
 * 
 * @author Administrator
 *
 */
public class StaticInnerClassesDemo {
    //加载 class StaticInnerClassesDemo这个类型 并不会立刻加载静态内部类private static class StaticInnerClasses
    //而是当你真正加载时 调用getInstance()方法时 才加载静态内部类
    
    private static class StaticInnerClasses {
        
        private static final StaticInnerClassesDemo staticInnerClasses= new StaticInnerClassesDemo();

    }
    //提供一个方法获取对象
    public static StaticInnerClassesDemo getInstance(){
        //通过类。方法 的方式 获得对象
        return StaticInnerClasses.staticInnerClasses;
    }
    //构造器私有
    private StaticInnerClassesDemo(){
        
    }

}

枚举单例模式

package com.gof23.singleton;
/**
 * 枚举单例 :         线程安全效率高 ,但不能延时加载
 * 
 * 避免了反射和反序列化的漏洞
 * 没有延时加载
 * @author Administrator
 *
 */
public enum  EnumDemo {
    //这个枚举元素本身就是单例对象
    INSTANCE;
    
    
    //添加自己需要的操作
    public void singletonOperation(){
        
    }
    

}

单例模式三要素

1. 构造方法私有化
2. 静态属性指向实例
3. public static的 getInstance方法,返回第二步的静态属性

以上是关于设计模式23之一一单例模式5的主要内容,如果未能解决你的问题,请参考以下文章

23天读懂23种设计模式:单例模式(创建型)

GOF23之一单例模式详细全解

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

23种设计模式之单例模式

23种设计模式一:单例模式

Android设计模式之单例模式的七种写法