设计模式 | 单例模式(singleton)

定义:

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

结构:(书中图,侵删)

结构超简单。就在你想控制实例数的类上操作即可。
1.定义一个static的对象引用
2.私有化构造方法
3.提供一个获取实例的方法(static的)
 

实例:

这又是一个在面试中频繁出现的设计模式,我至今不知道为什么大家那么偏爱这个模式。
而且基本上都是让你现场写一个单例模式的例子,基于这个很现实的原因,这个模式也好好好掌握。
我这里就不举生活中的例子了,直接上代码。
 
单例模式又分为两种形式:
一、饿汉式:在类加载是就初始化实例。
二、懒汉式:在第一次调用的时候,才初始化实例。
 
饿汉式:
package designpattern.singleton;

public class HungrySingleton {
    private static HungrySingleton instance = new HungrySingleton();// 静态初始化

    private HungrySingleton() {// 私有化构造方法
    }

    public static HungrySingleton GetInstance() {// 获取实例,static的
        return instance;
    }
}
懒汉式:
package designpattern.singleton;

public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {// 私有化构造方法

    }

    public static LazySingleton getInstance() {// 获取实例,static的
        if (instance == null) {
            instance = new LazySingleton();// 方法中创造实例
        }
        return instance;
    }
}
但是,如果是在多线程的情况下,可能会造成创造出两个实例的情况,可以考虑在getInstance方法上加上synchronized修饰:
package designpattern.singleton;

public class LazySingleton2 {
    private static LazySingleton2 instance;

    private LazySingleton2() {

    }

    public static synchronized LazySingleton2 getInstance() {// synchronized 修饰
        if (instance == null) {
            instance = new LazySingleton2();
        }
        return instance;
    }
}
这个可以进一步优化,只让线程在还没有实例化的情况下加锁:

package designpattern.singleton;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LazySingleton3 {
    private static LazySingleton3 instance;
    private static Lock lock = new ReentrantLock();

    private LazySingleton3() {

    }

    public static synchronized LazySingleton3 getInstance() {
        try {
            if (instance == null) {
                lock.lock();
                if (instance == null) {// 有必要再次判断,不然还是存在线程安全问题
                    instance = new LazySingleton3();
                }
                lock.unlock();
            }
        } finally {// 保证锁被释放
            lock.unlock();
        }
        return instance;
    }
}

总结:

饿汉式,在类加载是就初始化实例,要提前占用系统资源,但是不用考虑多线程访问可能造成的创建多个实例的问题。
懒汉式,在第一次调用的时候,才初始化实例,不用提前占用系统资源,但是需要考虑到多线程访问的问题。
这个模式在所有需要控制实例数的情况下都能使用,最常见的两个例子,就是数据库连接池和线程池。
以下原因引用自https://www.cnblogs.com/gmq-sh/p/5948379.html《单例模式的常见应用场景》:
数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。
 
(0)

相关推荐

  • 设计模式之单例模式(Singleton Pattern)

    一.定义 一个类只有一个实例,且该类能自行创建这个实例的一种模式. 二.单例模式举例 例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各 ...

  • 初级必备:单例模式的7个问题

    故事 实话实说,关于单例模式,网上有N多个版本.你估计也看过很多版本.但看完了又能怎样?我技术群里的一位小伙伴,上周面试,就因为一个单例模式,然后叫他回去等通知了. 下面是这位同学被问到的问题: 1. ...

  • 【设计模式】单例模式(Singleton Pattern)

    懒汉式 public class Singleton { private static Singleton instance; private Singleton() {}; public stati ...

  • 【转】C#设计模式-单例模式(Singleton Pattern)

    目录 介绍 第一个版本 --不是线程安全的 第二个版本 -- 简单的线程安全 第三个版本 - 使用双重检查锁定尝试线程安全 第四个版本 - 不太懒,不使用锁且线程安全 第五版 - 完全懒惰的实例化 第 ...

  • 设计模式-单例模式

    单例模式 优点 由于单例模式在内存中只有一个实例,减少了内存开支,特别是 一个对象需要频繁地创建.销毁时,而且创建或销毁时性能又无法优 化,单例模式的优势就非常明显. 由于单例模式只生成一个实例,所以 ...

  • Python单例模式(Singleton)的N种实现

    很多初学者喜欢用全局变量,因为这比函数的参数传来传去更容易让人理解.确实在很多场景下用全局变量很方便.不过如果代码规模增大,并且有多个文件的时候,全局变量就会变得比较混乱.你可能不知道在哪个文件中定义 ...

  • 浅谈C++设计模式--单例模式

    单例模式(Singleton)[分类:创建型] [目的:为程序的某个类的访问,提供唯一对象实例] 这估计是设计模式里面最简单的一个类了,下面我们一起看看,单例它是什么?以及如何实现一个单例 基本定义 ...

  • 设计模式-单例模式code

    package singeton; import java.security.SecureRandom; /** * @author Zero * @since 2019-08-13. * Descr ...

  • JAVA设计模式---单例模式篇

    单例模式(singleton):是JAVA中最简单的一种设计模式,属于创建型模式.所谓单例,就是整个程序有且仅有一个实例. 特点: 构造方法私有化 在本类中实例化一个对象作为本类的属性 对外提供一个访 ...

  • 创建型设计模式--单例模式

    一.单例模式 1.什么是单例模式 采取一定的方法,使程序中的某个类只存在一个实例对象,且该类对外提供一个获取该对象的方法(一般为静态方法). 2.单例模式分类 (1)饿汉式(2种写法,线程安全) 静态 ...