zoukankan      html  css  js  c++  java
  • 设计模式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方法,返回第二步的静态属性

  • 相关阅读:
    CF1168B Good Triple 性质分析
    bzoj 4994: [Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组_排序
    BZOJ 3940: [Usaco2015 Feb]Censoring AC自动机+栈
    BZOJ 1691 [Usaco2007 Dec]挑剔的美食家 multiset+排序+贪心
    BZOJ 1725: [Usaco2006 Nov]Corn Fields牧场的安排 状压动归
    BZOJ 1726: [Usaco2006 Nov]Roadblocks第二短路 Dijkstra
    BZOJ 1666: [Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏 幼儿园测试题
    BZOJ 5508: [Tjoi2019]甲苯先生的字符串 矩阵乘法_思维
    BZOJ 1602: [Usaco2008 Oct]牧场行走 倍增裸题
    描述符get/set/delete,init/new/call,元类
  • 原文地址:https://www.cnblogs.com/PoeticalJustice/p/7739419.html
Copyright © 2011-2022 走看看