zoukankan      html  css  js  c++  java
  • 创建型设计模式之单例模式


    单例模式使用场景:
    需要频繁和创建和销毁的对象
    创建对象耗时过多或消耗资源过多,即重量级对象,但又经常用到的对象
    工具类对象,频繁访问数据库或文件的对象(如数据源、session工厂等)
    Runtime就是精典的饿汉单例模式应用
    public class Runtime {
        private static Runtime currentRuntime = new Runtime();
    
        /**
         * Returns the runtime object associated with the current Java application.
         * Most of the methods of class <code>Runtime</code> are instance
         * methods and must be invoked with respect to the current runtime object.
         *
         * @return  the <code>Runtime</code> object associated with the current
         *          Java application.
         */
        public static Runtime getRuntime() {
            return currentRuntime;
        }
    
        /** Don't let anyone else instantiate this class */
        private Runtime() {}
    
    
    public static void main(String[] args) {
       //精典的饿汉模式
      Runtime.getRuntime();

    Singleton s1 = Singleton.Instance;
    Singleton s2= Singleton.Instance;
    System.out.println(s1==s2);
    System.out.println(s1.hashCode());
    System.out.println(s2.hashCode());
    s1.sayHello();
    }
    /**
     * 饿汉式(静态变量)
     * 优点:写法简单,在类装载时完成实例化,避免了线程同步问题
     * 缺点:装载时完成实例化,没有达到懒加载效果,如果不使用这个实例,造成内存浪费。
     * 结论:可用,会造成内存浪费。
     */
    public class Singleton {
    
        //1. 构造器私有化,外部不能new
        private  Singleton(){
    
        }
    
        //2. 内部创建实类对象
        private final static Singleton instance = new Singleton();
    
        //3. 对外提供静态方法,返回对象实例
        public static Singleton getInstance(){
            return instance;
        }
    }
    
    /**
     * 饿汉式(静态代码块)
     * 优点:写法简单,在类装载时完成实例化,避免了线程同步问题
     * 缺点:装载时完成实例化,没有达到懒加载效果,如果不使用这个实例,造成内存浪费。
     * 结论:可用,会造成内存浪费。
     */
    public class Singleton {
    
        //1. 构造器私有化,外部不能new
        private  Singleton(){
    
        }
    
        //2. 静态代码块中创建实类对象
        private final static singleton.type2.Singleton instance;
        static{
            instance = new singleton.type2.Singleton();
        }
    
        //3. 对外提供静态方法,返回对象实例
        public static singleton.type2.Singleton getInstance(){
            return instance;
        }
    }
    /**
     * 懒汉式(线程不安全)
     * 只能在单线程下使用
     */
    public class Singleton {
        private Singleton(){};
    
        private static Singleton instance;
    
        public static Singleton GetInstance(){
            if(instance==null){
                instance= new Singleton();
            }
            return instance;
        }
    }
    
    
    /**
     * 懒汉式(同步方法解决线程安全)
     * 效率低
     */
    public class Singleton {
        private static Singleton instance;
        private Singleton(){};
        public static synchronized Singleton getInstance(){
            if(instance==null){
                instance=new Singleton();
            }
            return instance;
        }
    }
    
    /**
     * 同步代码块解决线程安全
     * 不推荐
     */
    public class Singleton {
        private static Singleton instance;
        private Singleton(){};
        public static Singleton getInstance(){
            if(instance==null){
                synchronized (Singleton.class){
                    instance=new Singleton();
                }
            }
            return instance;
        }
    }
    /**
     * 双重检查
     * 线程安全,延迟加载,效率较高
     * 推荐使用
    
     双重校验锁法会有怎样的情景:
     * STEP 1. 线程A访问getInstance()方法,因为单例还没有实例化,所以进入了锁定块。
     * STEP 2. 线程B访问getInstance()方法,因为单例还没有实例化,得以访问接下来代码块,而接下来代码块已经被线程1锁定。
     * STEP 3. 线程A进入下一判断,因为单例还没有实例化,所以进行单例实例化,成功实例化后退出代码块,解除锁定。
     * STEP 4. 线程B进入接下来代码块,锁定线程,进入下一判断,因为已经实例化,退出代码块,解除锁定。
     * STEP 5. 线程A初始化并获取到了单例实例并返回,线程B获取了在线程A中初始化的单例。
     * 理论上双重校验锁法是线程安全的,并且,这种方法实现了lazyloading。
     */
    public class Singleton {
        private static volatile Singleton instance;
        private Singleton(){};
        public static Singleton getInstance(){
            if(instance==null){
                synchronized (Singleton.class){
                    if(instance==null){
                        instance=new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    
    /**
     * 静态内部类不会在单例加载时就加载,而是在调用getInstance()方法时才进行加载,
     * 达到了类似懒汉模式的效果, *而这种方法又是线程安全的。
     */
    public class Singleton {
    
        private static class SingletonInstantce{
            private final static Singleton instance = new Singleton();
        }
    
        private Singleton(){
    
        }
    
        public static Singleton getInstance(){
            return SingletonInstantce.instance;
        }
    }
    
    /**
     * 枚举法
     */
    public enum Singleton {
        Instance;
        public void sayHello(){
            System.out.println("hello");
        }
    }
  • 相关阅读:
    Xcode ARC,非ARC混搭
    Xcode GData库解析XML
    NSThread
    自定义UITableViewCell中的button实现视图切换
    UITableView
    iOS事件响应链
    结构体和NSData相互转换
    UIView的transform属性
    javascript垃圾回收机制
    ios8 滚动事件解放了
  • 原文地址:https://www.cnblogs.com/huangzhen22/p/14487132.html
Copyright © 2011-2022 走看看