Java设计模式(一)单例模式

Author Avatar
wshunli 9月 05, 2018
  • 在其它设备中阅读本文章

单例模式(Singleton Pattern)确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

特点
单例类只能有一个实例。
单例类必须自己创建自己的唯一实例。
单例类必须给所有其他对象提供这一实例。

单例模式

单例模式的其他几种实现方式:

1、饿汉模式,线程安全

public class Singleton {
    private static final Singleton instance = new Singleton();
    private Singleton() {
    }
    public static Singleton getInstance() {
        return instance;
    }
}

饿汉模式单例会在加载类后一开始就被初始化,即使客户端没有调用 getInstance() 方法。

2、懒汉模式,线程不安全

public class Singleton {
    private static Singleton instance;
    private Singleton() {
    }
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

当有多个线程并行调用 getInstance() 的时候,就会创建多个实例。也就是说在多线程下不能正常工作。

3、懒汉模式、线程安全:

public class Singleton {
    private static Singleton instance;
    private Singleton() {
    }
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

虽然做到了线程安全,并且解决了多实例的问题,但是它并不高效。

因为在任何时候只能有一个线程调用 getInstance() 方法。但是同步操作只需要在第一次调用时才被需要,即第一次创建单例实例对象时。

4、双检锁/双重校验锁(DCL,即 double-checked locking)

public class Singleton {
    private volatile static Singleton instance;
    private Singleton() {
    }
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

5、静态内部类

public class Singleton {  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE; 
    }  
}

6、枚举

public enum Singleton{
    INSTANCE;
}

总结

一般来说,单例模式有五种写法:懒汉、饿汉、双重检验锁、静态内部类、枚举。上述所说都是线程安全的实现,上文中第一种方式线程不安全,排除。

一般情况下直接使用饿汉式就好了,如果明确要求要懒加载(lazy initialization)倾向于使用静态内部类。如果涉及到反序列化创建对象时会试着使用枚举的方式来实现单例。

参考资料
1、单例模式 | 菜鸟教程:
http://www.runoob.com/design-pattern/singleton-pattern.html

如果本文对您有所帮助,且您手头还很宽裕,欢迎打赏赞助我,以支付网站服务器和域名费用。 https://paypal.me/wshunli 您的鼓励与支持是我更新的最大动力,我会铭记于心,倾于博客。
本文链接:https://www.wshunli.com/posts/d1c4534.html