单件设计模式|简介 singleton模式是最简单的设计模式之一。有时我们只需要类的一个实例,例如一个由多个对象共享的DB连接,因为为每个对象创建一个单独的DB连接可能代价高昂。类似地,应用程序中可以有一个配置管理器或错误管理器来处理所有问题,而不是创建多个管理器。 定义: singleton模式是一种设计模式,它将类的实例化限制为一个对象。 让我们看看实现这样一个类的各种设计选项。如果你能很好地处理静态类变量和访问修饰符,这应该不是一项困难的任务。 方法1:经典实现
JAVA
// Classical Java implementation of singleton // design pattern class Singleton { private static Singleton obj; // private constructor to force use of // getInstance() to create Singleton object private Singleton() {} public static Singleton getInstance() { if (obj== null ) obj = new Singleton(); return obj; } } |
这里我们声明了getInstance()static,这样我们就可以在不实例化类的情况下调用它。第一次调用getInstance()时,它会创建一个新的单例对象,然后返回相同的对象。请注意,直到我们需要它并调用getInstance()方法时,才会创建Singleton obj。这被称为惰性实例化。 上述方法的主要问题是它不是线程安全的。考虑下面的执行顺序。
此执行序列为singleton创建两个对象。因此,这个经典的实现不是线程安全的。 方法2:使getInstance()同步
JAVA
// Thread Synchronized Java implementation of // singleton design pattern class Singleton { private static Singleton obj; private Singleton() {} // Only one thread can execute this at a time public static synchronized Singleton getInstance() { if (obj== null ) obj = new Singleton(); return obj; } } |
这里使用synchronized可以确保一次只有一个线程可以执行getInstance()。 这种方法的主要缺点是,每次创建singleton对象时都使用synchronized非常昂贵,可能会降低程序的性能。然而,如果getInstance()的性能对应用程序来说并不重要,那么这个方法提供了一个简洁的解决方案。 方法3:渴望实例化
JAVA
// Static initializer based Java implementation of // singleton design pattern class Singleton { private static Singleton obj = new Singleton(); private Singleton() {} public static Singleton getInstance() { return obj; } } |
这里我们在静态初始化器中创建了singleton的实例。JVM在加载类时执行静态初始值设定项,因此这保证是线程安全的。仅当singleton类较轻且在整个程序执行过程中使用时,才使用此方法。 方法4(最佳):使用“ 双重检查锁定 ” 如果您注意到,一旦创建了一个对象,同步就不再有用了,因为现在obj将不为null,任何操作序列都将导致一致的结果。 因此,当obj为null时,我们只会获取getInstance()上的锁一次。这样,我们只需同步第一种方式,这正是我们想要的。
JAVA
// Double Checked Locking based Java implementation of // singleton design pattern class Singleton { private static volatile Singleton obj = null ; private Singleton() {} public static Singleton getInstance() { if (obj == null ) { // To make thread safe synchronized (Singleton. class ) { // check again as multiple threads // can reach above step if (obj== null ) obj = new Singleton(); } } return obj; } } |
我们已经宣布了obj 不稳定的 这确保多个线程在初始化为单实例时正确提供obj变量。这种方法大大减少了每次调用同步方法的开销。 参考资料: 首件设计模式手册(强烈推荐) https://en.wikipedia.org/wiki/Singleton_pattern 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论