单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
特点
单例模式有以下特点:
- 单例类只能有一个实例
- 单例类必须自己创建自己的唯一实例
- 单例类必须给所有其他对象提供这一实例
实现
饿汉式
饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。
1 2 3 4 5 6 7 8 9 10 11 12
| public class Singleton {
private static final Singleton single = new Singleton(); private Singleton() {} public static Singleton getInstance() { return single; } }
|
懒汉式
懒汉式则是在调用获取实例对象的方法时检查,若没有对象则创建对象,如果单例对象已经存在则不创建对象直接返回已存在的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Singleton { private static Singleton single=null;
private Singleton() {} public static Singleton getInstance() { if (single == null) { single = new Singleton(); } return single; } }
|
这种懒汉式实现是非线程安全的,并发环境下很可能出现多个Singleton实例。若要保证线程安全,我们可以使用如下几种方式
1 2 3 4 5 6
| public static synchronized Singleton getInstance() { if (single == null) { single = new Singleton(); } return single; }
|
1 2 3 4 5 6 7 8 9 10
| public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Singleton { private static class LazyHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton() {} public static final Singleton getInstance() { return LazyHolder.INSTANCE; } }
|
其中第三种实现方式最好,避免了加锁的效率问题。但实际开发中饿汉式使用较多。