GOF设计模式之单例模式
Posted 寒松,
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GOF设计模式之单例模式相关的知识,希望对你有一定的参考价值。
GOF设计模式之单例模式
单例模式即保证类只有一个实例,并且提供一个访问该实例的全局访问点。定义一个类,将其属性私有化、构造器也私有化,只留下一个方法给外部调用。比较适用调用和销毁频繁的类、一些工具类对象、创建时耗时或者占用资源又不得不用的类、一些访问频繁的数据库和文件对象。
其五种写法
一、懒汉式
public class Singleton
//类初始化时,立即加载这个对象(没有延时加载的优势),类加载是天然的线程安全
private static Singleton instance = new Singleton();
private Singleton()
//方法没有同步,调用效率高
public static Singleton getInstance()
return instance;
二、饿汉式
public class Singleton
//类初始化时,不初始化(延时加载,到要用的时候在加载)
private static Singleton instance;
private Singleton()
//方法同步,调用效率低
public static synchronized Singleton getInstance()
if(instance == null )
instance = new Singleton();
return instance ;
三、双重检测锁式
public class Singleton
private static Singleton instance = null;
public static Singleton getInstance()
/*虽然也添加了同步块,但是同步块再if之下,只有第一次才
* 进行同步,不必每次获取对象都进行同步,提高了执行效率。*/
if(instance ==null)
Singleton sc;
synchronized (Singleton.class)
sc = instance ;
synchronized (Singleton.class)
if(sc == null)
sc = new Singleton();
instance = sc;
return instance ;
private Singleton()
//由于编译器优化原因和JVM底层内部模型原因,偶尔回出现问题,慎用!
四、静态内部类式
public class Singleton
//调用此方法时才创建对象且线程安全,并且实现了延时加载,调用效率高。
private static class SingletonClassInstance
private static final Singleton instance = new Singleton();
private Singleton()
public static Singleton getInstance()
return SingletonClassInstance.instance;
五、枚举式
public enum Singleton
//这个枚举本身就是一个单例对象,且天然线程安全,但是无法延时加载
INSTANCE;
//可以添加自己需要的操作
public void SingletonOperation()
如何避免反射漏洞
首先需要了解时怎么通过反射漏洞的,就是调用了**.setAccessible(true);**方法使其跳过权限检查,从而可以直接访问其私有的成员,从二直接创建对象。如何避免呢?可以直接在类内部私有无参构造器中添加一个判断即可
private Singleton()
//判断instance是否创建,如果不为空直接抛出异常即可。
if(instance != null)
throw new RuntimeException();
如何避免反序列化漏洞
反序列化漏洞是将已经创建的类对象通过序列化存储到文件中,再通过反序列化将文件读取,从而创建一个新的类对象。避免方法即在类中添加下面这个私有方法
//反序列化时,如果创建了readResolve()则直接返回此方法指定的对象,不需要再创建新对象
private Object readResolve()
return instance;
如何选用
1、单例对象如果占用资源少不需要延时加载:枚举比饿汉式好;
2、单例对象占用资源大需要延时加载:静态内部类好于懒汉式。
学习笔记,如有不对的地方,烦请大神帮忙指点指点!
以上是关于GOF设计模式之单例模式的主要内容,如果未能解决你的问题,请参考以下文章