单例设计模式介绍

153 阅读3分钟

1.什么是单例模式:

在有些系统中,为了节省内存资源、保证数据内容的一致性,对某些类要求只能创建一个实例,这就是所谓的单例模式。

2.单例模式的定义与特点:

定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。

特点:

  • 单例类只有一个实例对象;
  • 该单例对象必须由单例类自行创建;
  • 单例类对外提供一个访问该单例的全局访问点;
3.单例模式的实现:

单例模式是设计模式中最简单的模式之一。通常,普通类的构造函数是公有的,外部类可以通过“new 构造函数()”来生成多个实例。但是,如果将类的构造函数设为私有的,外部类就无法调用该构造函数,也就无法生成多个实例。这时该类自身必须定义一个静态私有实例,并向外提供一个静态的公有函数用于创建或获取该静态私有实例。

Singleton 模式通常有两种实现形式:

饿汉式:

package singleton;

/**
 * 饿汉式单例
 * 特点:类一旦加载就创建一个单例,保证在调用getInstance方法之前单例已经存在了
 */
public class HungrySingleton {
    private static final HungrySingleton instance = new HungrySingleton();
    //私有构造,避免外部初始化
    private HungrySingleton() {
    }
    //静态公有方法,获取该实例对象
    public static HungrySingleton getInstance() {
        return instance;
    }
}

懒汉式第一种:

package singleton;

/**
 * 懒汉式单例
 * 特点:只有在调用getInstance方法时才会创建实例对象
 */
public class LazySingleton {
    private static LazySingleton instance = null;
    private LazySingleton() {
    }
    /**
     * 问题:
     * 使用synchronized关键字修饰,可以保证线程安全性;
     * 但同时有synchronized关键字修饰,所以该多线程访问时,都要判断锁,会导致效率较低
     */
    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

懒汉式第二种:

package singleton;

/**
 * 懒汉式更好的解决方案:使用双判断的方式
 */
public class Lazy {
    public static Lazy instance = null;
    private Lazy() {
    }
    /**
     * 使用双重判断的方式来解决懒汉式的效率问题,即当一个线程创建了该实例对象,以后的线程访问的时候该对象      * 就不为null,既不用再去判断锁了,这样可以减少判断锁的次数,提高了效率
     */
    public static Lazy getInstance() {
        if (instance == null) {
            //静态方法的锁使用的是改静态方法所在类的class文件对象
            synchronized (Lazy.class) {
                if (instance == null) {
                    instance = new Lazy();
                }
            }
        }
        return instance;
    }
}

1.懒汉式和饿汉式的区别:

懒汉式的特点在于实例的延迟(所以是汉式)加载;

2.懒汉式有什么问题:

如果多线程访问时会出现安全问题,可以加同步(synchronized)来解决,但是效率较低

3.怎么解决懒汉式效率低的问题:

可以使用双重判断可以解决这个问题

4.加同步的时候,使用的锁是哪一个:

该类所属的字节码文件对象(静态)