单例模式
饿汉式:线程安全的
静态常量写法
Class Bank{ //私有化类的构造器,类的外部无法通过构造器new对象 private Bank(){ } //内部创建类的对象,此对象也是静态的,因为静态方法只能调静态对象 private static Bank instance = new Bank(); //提供公共的静态方法,返回类的对象。这样就可以巧妙的避开在类的外部new对象 public static Bank getInstance(){ return instance; } } psvm{ Bank b1 = Bank.getInstance(); Bank b2 = Bank.getInstance(); sout(b1 == b2);//true,都是类中new的对象 }
优点:类装载时就完成了实例化,避免了线程同步的问题
缺点:类装载时就完成实例化,如果从始至终没有用过这个实例,造成内存的浪费静态代码块写法
Class Bank{ //私有化类的构造器,类的外部无法通过构造器new对象 private Bank(){ } //内部创建类的对象,此对象也是静态的,因为静态方法只能调静态对象 private static Bank instance; static{ instance = new Bank(); } //提供公共的静态方法,返回类的对象。这样就可以巧妙的避开在类的外部new对象 public static Bank getInstance(){ return instance; } } psvm{ Bank b1 = Bank.getInstance(); Bank b2 = Bank.getInstance(); sout(b1 == b2);//true,都是类中new的对象 }
优缺点同上
懒汉式
线程不安全写法
Class Bank{ private static Bank instance; private Bank(){} public static Bank getInstance(){ if(instance== null){ instance = new Bank(); }return instance; } }
优点:起到了用的时候才创建的效果,
缺点:但只在单线程下是线程安全的。多线程下可能产生多个实例线程安全写法
Class Bank{ private static Bank instance; private Bank(){} //加入同步处理代码,解决多线程不安全的问题 public static synchronized Bank getInstance(){ if(instance == null){ instance= new Bank(); }return instance; } }
优点:解决类线程安全的问题
缺点:效率变低,每次都需要去进行同步检测双重检查方式
Class Bank{ private static volatile Bank instance; private Bank(){} //加入同步处理代码,解决多线程不安全的问题 public static synchronized Bank getInstance(){ Synchronized(Bank.class){ if(instance == null){ nstance= new Bank(); }return instance; } }
静态内部类写法,推荐
Class Bank{ private static volatile Bank instance; private Bank(){} //静态内部类 private static class SingletonInstance(){ private static final Bank INSTANCE = new Bank(); } public static synchronized Bank getInstance(){ return SingletonInstance.INSTANCE; } }
优点:
- 类装载机制保证初始化实例时只有一个线程
- SingletonInstance被装载时不会立即实例化,,而是在需要时调用,才会装载
- 静态内部类只会在第一次加载类时初始化,JVM保证了线程的安全,在类的初始化时,别的线程无法进入
- 避免了线程不安全,同时也延迟加载,效率高