• 单例模式/singleton模式/创建型模式


    Java实现要点:

    • 私有构造方法
    • 线程安全(并发的考虑)
    • 延迟加载(效率的考虑,对于较大的类在使用时在加载)
    • 公有方法访问单一实例

    常见单例模式代码及问题

    //无延迟加载,常驻内存(即使不使用)
    class Singleton {
        private final static Singleton INSTANCE = new Singleton();
    	private Singleton() {
    	}
    	public static Singleton getInstance() {
    		return INSTANCE;
    	}
    }
    
    
    //无延迟加载,常驻内存(即使不使用)
    public class Singleton {
        private static Singleton instance;
        static {
            instance = new Singleton();
        }
        private Singleton() {}
        public Singleton getInstance() {
            return instance;
        }
    }
    
    
    //非线程安全
    public class Singleton {
        private static Singleton singleton;
        private Singleton() {}
        public static Singleton getInstance() {
            if (singleton == null) {
                singleton = new Singleton();
            }
            return singleton;
        }
    }
    
    
    //同步粒度大,初始化后效率低
    public class Singleton {
        private static Singleton singleton;
        private Singleton() {}
        public static synchronized Singleton getInstance() {
            if (singleton == null) {
                singleton = new Singleton();
            }
            return singleton;
        }
    }
    
    
    //非线程安全
    public class Singleton {
        private static Singleton singleton;
        private Singleton() {}
        public static Singleton getInstance() {
            if (singleton == null) {
            //多线程可以同时到这
                synchronized (Singleton.class) {
                    singleton = new Singleton();
                }
            }
            return singleton;
        }
    }
    
    

    推荐单例模式代码示例:

    //双重检测,线程安全,延迟加载,效率较好
    public class Singleton {
        private static volatile Singleton singleton;
        private Singleton() {}
        public static Singleton getInstance() {
            if (singleton == null) {
                synchronized (Singleton.class) {
                    if (singleton == null) {
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }
    
    
    //降低同步粒度,线程安全,延迟加载,效率较好
    public class Singleton4 {
        private static Singleton4 instance=null;
    	private Singleton4 () {
    	}
    	private static synchronized  void synUnit() {
    		if (instance==null) {
    			instance=new Singleton4();			
    		}
    	}
    	public static  Singleton4 getInstance() {
    		if (instance==null) {
    			synUnit();
    		}
    		return instance;
    	}
    }
    
    
        /*
    	 * 使用内部类来维护单例的实现,JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。
    	 * 这样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance只被创建一次,并且会保证把赋值给instance的内存初始化完毕,
    	 * 这样我们就不用担心上面的问题。同时该方法也只会在第一次调用的时候使用互斥机制,这样就解决了低性能问题。
    	 * 
    	 * */
    public class Singleton {
        private Singleton() {}
        private static class SingletonInstance {
            private static final Singleton INSTANCE = new Singleton();
        }
        public static Singleton getInstance() {
            return SingletonInstance.INSTANCE;
        }
    }
    
    
    //单枚举类型,实现单例,无偿提供序列化,Effective Java推荐的方式。
    public enum Singleton {
        INSTANCE;
    	public void method() {
    		System.out.println("hello world");
    	}
    }
    
    

    总结

    • synchronized关键字锁定的是对象,在用的时候,一定要在恰当的地方使用(注意需要使用锁的对象和过程,可能有的时候并不是整个对象及整个过程都需要锁)。

    静态类

    • 静态类不能实现接口。(从类的角度说是可以的,但是那样就破坏了静态了。因为接口中不允许有static修饰的方法,所以即使实现了也是非静态的)。
    • 单例可以被延迟初始化,静态类一般在第一次加载是初始化。之所以延迟加载,是因为有些类比较庞大,所以延迟加载有助于提升性能。
    • 单例类可以被继承,他的方法可以被覆写。但是静态类内部方法都是static,无法被覆写。

    参考这里



    I am a slow walker, but I never walk backwards.



  • 相关阅读:
    TP框架的小知识
    执行sql语句的注意事项
    关于引用值的总结
    几道经典容易错的php面试题
    Smarty模板的学习_2
    Smarty模板的学习_1
    数据库的权限操作
    redhat与zlib兼容性问题?
    Ubuntu中Qt Creator无法启动调试
    ubuntu下安装chrome浏览器和flash插件
  • 原文地址:https://www.cnblogs.com/lknny/p/4836246.html
Copyright © 2020-2023  润新知