Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点
其实我们可以通过反射从而越过私有化构造函数 得到该类的对象从而使单例模式失效
//单例模式之饿汉模式
public class Singleton {
//实例化对象 并且设置为私有静态成员变量
private static final Singleton instance = new Singleton();
private Singleton(){
}
//外界获取该类对象方法 所以是公有的
public Singleton getInstance(){
return instance;
}
}
在类加载的时候就完成静态成员变量的初始化,所以调用getInstance方法的时候就不存在线程安全的问题,但是这样也同样带来一个问题,就是目前我不需要这个类的对象,但是它已经帮我创建并且初始化,占据一块内存空间,而且因为是静态成员变量,因此只有当类卸载的时候才会释放对象的内存空间。
//单例模式之懒汉模式-1
public class Singleton {
//创建对象引用不实例化 并且设置为私有静态成员变量
private static Singleton instance;
private Singleton(){
}
//使用synchronized保证多线程操作时候线程安全
public synchronized Singleton getInstance(){
if(instance == null )
instance = new Singleton();
return instance;
}
}
只创建了对象的引用 但是并没有实例化对象 而是只有当我们第一调用的getInstance方法的时候才实例化,这样就解决了饿汉模式浪费内存空间的问题,但是这样也存在一个多线程操作时线程安全的问题 所以必须需要synchronized关键字保证线程安全。因为使用synchronized可能在多线程操作效率比较低所以看看第二种懒汉模式
//单例模式之懒汉模式-2
public class Singleton {
//创建对象引用不实例化 并且设置为私有静态成员变量
// 使用volatile 保证变量的可见性
private static volatile Singleton instance;
private Singleton(){
}
//使用synchronized保证多线程操作时候线程安全
public Singleton getInstance(){
// 对象实例化时与否判断(不使用同步代码块,instance不等于null时,直接返回对象,提高运行效率)
if (instance == null) {
//同步代码块(对象未初始化时,使用同步代码块,保证多线程访问时对象在第一次创建后,不再重复被创建)
synchronized (Singleton.class) {
//未初始化,则初始instance变量
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
volatile 保证变量线程安全 当我们使用valatile修饰一个变量的时候 当这个变量每次修改被修改后 jvm虚拟机保证这个变量从主内存加载到线程工作内存的值是最新的
单例模式的最佳实现。内存占用地,效率高,线程安全,多线程操作原子性。