这是一个设计模式,一个模式存在,那肯定有解决现实问题的能力
所以,单例模式解决的问题是要保证一个类的对象在内存中的唯一性,就是一个类的对象在内存中有且只有一个,内存中只能创建一个对象
应用场景
多个程序都在操作同一个配置文件时,需要程序A操作后的结果,程序B知道,并继续基于程序A操作后的结果进行操作。前提是数据都存储在配置文件对象中,要求程序A程序B操作的配置文件是同一个对象。
要限制其他程序不能随便创建这个类的对象,保证内存中只有一个对象。
创建对象是要调用构造函数的,那么只要将这个类的构造函数私有了,不让其他程序访问,其他程序就无法创建对象,但当私有构造函数后,其他程序无法创建对象,如果需要使用对象,可以在本类中创建自己的对象,对外提供获取本类对象的方法就可以了。
单例模式的代码体现和小问题
饿汉模式
public class Single {
//私有本类中的构造函数
private Single(){}
//创建本类对象
private static Single s = new Single();
//对外提供获取本来对象方法
public static Single getInstance(){
return s;
}
}
注意问题:
由于外界无法创建Single对象,没有对象,那就无法调用getInstance方法,这时需要将getInstance方法静态化,这样外界就可以通过类名直接调用该方法。
懒汉模式
public class Single
{
//私有构造函数
private Single(){}
//在本类中创建本类对象
private static Single instance = null;
//对外提供静态访问方法,获取本类实例对象
public static Single getInstance(){
if(instance == null ) // 这里会有线程安全问题
{
instance = new Single();
}
return instance;
}
}
class SingleDemo
{
public static void main(String[] args)
{
//获取Single类的实例对象s
Single s = Single.getInstance();
//获取Single类的实例对象s2
Single s2 = Single.getInstance();
System.out.println(s==s2); //true
}
}
单例模式的应用
懒汉模式,它的特点是运行时获得对象的速度比较慢,但加载类的时候比较快。它在整个应用的生命周期只有一部分时间在占用资源。
饿汉模式,它的特点是加载类的时候比较慢,但运行时获得对象的速度比较快。它从加载到应用结束会一直占用资源。
这两种模式对于初始化较快,占用资源少的轻量级对象来说,没有多大的性能差异,选择懒汉式还是饿汉式都没有问题。但是对于初始化慢,占用资源多的重量级对象来说,就会有比较明显的差别了。所以,对重量级对象应用饿汉模式,类加载时速度慢,但运行时速度快;懒汉模式则与之相反,类加载时速度快,但运行 时第一次获得对象的速度慢。
从用户体验的角度来说,我们应该首选饿汉模式。我们愿意等待某个程序花较长的时间初始化,却不喜欢在程序运行时等待太久,给人一种反应迟钝的感觉,所以对于有重量级对象参与的单例模式,我们推荐使用饿汉模式。