介绍
单例模式要点:
种类
饱汉式
优点:实现简单,安全
缺点:唯一的对象在类本身完成实例化的时候就会被构造,但如果从未使用过这个对象,就会造成内存浪费。
比如下面代码,只是使用了静态方法,未使用过对象,但对象也被构造了,并且会自始至终都存在。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class SingleTon { private SingleTon() { System.out.println("构造函数被调用"); } private final static SingleTon INSTANCE=new SingleTon(); public static SingleTon getInstance() { return INSTANCE; } public static void method() { System.out.println("method方法被调用"); } } public class MyTest { public static void main(String[] args) { SingleTon.method(); } }
|
执行结果:
构造函数被调用
method方法被调用
懒汉式[不可用]
优点:实现了 Lazy Loading,在下面代码中可以看出,不使用 INSTANCE 的时候 INSTANCE 是不会初始化的。
缺点:多线程下不安全,如果线程 A 进入了 if(INSTANCE == null) 的判断后被打断,线程B又进入了 if(INSTANCE == null) ,并且继续执行,这时已经实例化了一个对象。A 再回来执行时,因为已经判断过了,所以又实例化了一个对象,就违反了单例的原则。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class SingleTon { private SingleTon() { System.out.println("构造函数被调用"); } private static SingleTon INSTANCE; public static SingleTon getInstance() { if(INSTANCE==null) { INSTANCE=new SingleTon(); } return INSTANCE; } public static void method() { System.out.println("method方法被调用"); } } public class LazySingleTon { public static void main(String[] args) { SingleTon.method(); } }
|
执行结果:
method方法被调用
懒汉式双重判断
针对懒汉式线程不安全问题有一个逐步的完善过程,双重判断是最终可用并且不影响效率的版本
优点:Lazy Loading 并且线程安全
缺点:书写麻烦(如果算的话)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class SingleTon { private SingleTon() { } private static SingleTon INSTANCE; public static SingleTon getInstance() { if (INSTANCE == null) synchronized (SingleTon.class) { if (INSTANCE == null) INSTANCE = new SingleTon(); } return INSTANCE; } }
|
内部静态类实现单例
优点:安全,高效,Lazy Loading
1 2 3 4 5 6 7 8 9 10 11 12 13
| class SingleTon { private SingleTon() {} private static class SingleTonInstance { private final static SingleTon INSTANCE=new SingleTon(); } public static SingleTon getInstance() { return SingleTonInstance.INSTANCE; } }
|
Reference
https://www.cnblogs.com/zhaoyan001/p/6365064.html
如有错误,请多指教