懒汉式与饿汉式的区别
1、饿汉式:在程序启动或单例模式类被加载的时候,单例模式实例就已经被创建。(线程安全,调用率高,但是,不能延迟加载。)
2、懒汉式:当程序第一次访问单例模式实例时才进行创建。(线程安全,调用效率不高,可以延时加载。)
如何选择:如果单例模式实例在系统中经常会被用到,饿汉式是一个不错的选择。饿汉式无需关注多线程问题、写法简单明了、能用则用。
反之如果单例模式在系统中会很少用到或者几乎不会用到,那么懒汉式是一个不错的选择。
其他:
1.双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题,不建议使用)
2.静态内部类式(线程安全,调用效率高。但是,可以延时加载)
3.枚举式(线程安全,调用率高,不能延时加载)
如何选用:
——单例对象 占用资源少,不需要 延时加载
枚举式 好于 饿汉式
——单例对象 占用资源大,需要延时加载
静态内部类式 好于 懒汉式
1、饿汉式:
public class Singleton{ private static Singleton singleton = new Singleton (); private Singleton (){} public static Singleton getInstance(){return singletion;} }
2、懒汉式:
public class Singleton{ private static Singleton singleton = null; public static synchronized synchronized getInstance(){ if(singleton==null){ singleton = new Singleton(); } return singleton; } }
3、双重检查
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; } }
4、静态内部类
public class Singleton { private Singleton() {} private static class SingletonInstance { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonInstance.INSTANCE; } }
5、枚举
public enum Singleton { INSTANCE; public void whateverMethod() { } }
借助JDK1.5中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。可能是因为枚举在JDK1.5中才添加,所以在实际项目开发中,很少见人这么写过。