单例模式属于创建型模式,是设计模式中比较简单的模式。在单例模式中,单一的类负责创建自己的对象,同时确保只有单个对象被创建。保证一个类仅有一个实例,并提供一个访问它的全局访问点。
举个栗子:
public class SingleObject {
//创建 SingleObject 的一个对象
private static SingleObject instance = new SingleObject();
//让构造函数为 private,这样该类就不会被实例化
private SingleObject(){}
//获取唯一可用的对象
public static SingleObject getInstance(){
return instance;
}
//显示信息
public void showMessage(){
System.out.println("Hello World!");
}
}
public class SingletonPatternDemo {
public static void main(String[] args) {
//这里我们就不应该用下面这条语句了
//SingleObject object = new SingleObject();
//因为构造函数 SingleObject() 是不可见的
//获取唯一可用的对象
SingleObject object = SingleObject.getInstance();
//显示消息
object.showMessage();
}
}
Hello World!
懒汉式是需要的时候才创建单实例(加入了成员变量是否为空的判断语句)。
懒汉式又分为线程安全和线程不安全的实现方式。
线程不安全的实现方式是基本的实现方式,但是这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized。
public class Singleton {
private static Singleton instance;
private Singleton() {};
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
使用 synchronized
进行加锁,保证单例,但是加锁会影响效率,导致效率较低。
public class Singleton {
private static Singleton instance;
private Singleton() {};
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
注意事项:
getInstance()
方法中需要使用同步锁 synchronized (Singleton.class)
防止多线程同时进入造成 instance 被多次实例化。
接下来我们介绍另一种单例模式的实现方式 -- 饿汉式。
该实现方式是在类加载的时候就创建单实例。实现起来比较简单,比较常用,但会产生垃圾对象。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {};
public static Singleton getInstance() {
return instance;
}
}
由于没有加锁,所以执行效率较高,但是由于类加载的时候就初始化,会浪费内存。