Java单例模式
单例模式 | 菜鸟教程 (runoob.com)
单例模式介绍
要点:
Java几种实现方式
首先提一下懒汉模式与饿汉模式:
然后就是多线程是否安全。
这里的线程安全是指,多线程可能创建多个单例对象。
1.最简单的懒汉模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Singleton{ private static Singleton instance; private Singleton(){} public static Singleton getInstance(){ if(instace == null){ instance = new Singleton(); } return instance; } }
|
2.懒汉模式方法加锁
1 2 3 4 5 6 7 8 9 10 11
| public class Singleton{ private static Singleton instance; private Singleton(); public static synchronized Singleton getInstace(){ if(instance == null){ instance = new Singleton(); } return instance; } }
|
直接给get方法加了锁,可能性能较低。
3. 双重验证
DCL:double-check locking
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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; } }
|
4. 饿汉式
1 2 3 4 5 6 7 8 9
| public class Singleton{ private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return instance; } }
|
上来就创建,浪费内存;容易产生垃圾对象。使用了 classloader 机制来保证了线程安全。
5.静态内部类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Singleton{ private Singleton(){} public static class SingletonHolder{ private static final Singlton INSTANCE = new Singleton(); } public static final getInstance(){ return SingletonHolder.INSTANCE; } }
|
SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance。
6.枚举
jdk1.5之后添加了enmu;
1 2 3 4 5 6
| public enmu Singleton{ INSTANCE; public void doSomething(){ System.out.println("Do Something!"); } }
|
不会被反射机制破解。
使用场景
一般直接使用饿汉式;
如要使用 懒汉式 则一般建议使用 静态内部类 的方法;
有特殊要求则使用 双重验证 方式;
如涉及 反序列化 则使用 枚举。