1 单例模式
保证在整个的软件系统中,对某个类只能存在一个对象实例, 并且该类只提供一个取得其对象实例的方法(静态方法)。
使用场景:需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session 工厂等)。
2 饿汉式**(静态常量)** -> 推荐
1 2 3 4 5 6 7 8 9 10 11
| public class Singleton01 { private final static Singleton01 instance = new Singleton01();
private Singleton01() { }
public static Singleton01 getInstance() { return instance; } }
|
优点:写法简单,就是在类装载的时候就完成实例化,避免了线程同步问题。
缺点:在类装载的时候就完成实例化,没有达到 Lazy Loading 的效果。如果没有使用,则会造成内存的浪费。
3 饿汉式(静态代码块)-> 推荐
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Singleton02 { private static Singleton02 instance;
static { instance = new Singleton02(); }
private Singleton02() { }
public static Singleton02 getInstance() { return instance; } }
|
这种单例模式可用,但是可能造成内存浪费。
4 懒汉式(线程不安全)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Singleton03 { private static Singleton03 instance;
private Singleton03() { }
public static Singleton03 getInstance() { if (instance == null) { instance = new Singleton03(); } return instance; } }
|
优点: Lazy Loading 的效果,只能在单线程下使用。
缺点:线程不安全。
5 懒汉式(线程安全,同步方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Singleton04 { private static Singleton04 instance;
private Singleton04() { }
public static synchronized Singleton04 getInstance() { if (instance == null) { instance = new Singleton04(); } return instance; } }
|
优点:解决了线程安全问题。
缺点:效率低,每个线程在想获得类的实例时候,执行 getInstance() 方法都要进行同步。
6 懒汉式(线程安全,同步代码块)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Singleton05 { private static Singleton05 instance;
private Singleton05() { }
public static Singleton05 getInstance() { if (instance == null) { synchronized (Singleton05.class) { instance = new Singleton05(); } } return instance; } }
|
优点:解决了线程安全问题。
缺点:效率低,每个线程在想获得类的实例时候,执行 getInstance() 方法都要进行同步。
7 双重检查(DCL) -> 推荐
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Singleton06 { private static volatile Singleton06 instance;
private Singleton06() { }
public static Singleton06 getInstance() { if (instance == null) { synchronized (Singleton06.class) { if (instance == null) { instance = new Singleton06(); } } } return instance; } }
|
线程安全;延迟加载;效率较高。
8 静态内部类 -> 推荐
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Singleton07 {
private Singleton07() { }
public static class SingletonInstance { private static final Singleton07 INSTANCE = new Singleton07(); }
public static Singleton07 getInstance() { return SingletonInstance.INSTANCE; } }
|
线程安全,利用静态内部类特点实现延迟加载,效率高。
9 枚举 -> 推荐
1 2 3 4
| public enum Singleton08 { INSTANCE; }
|
不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。