饿汉式

  • 饿汉式单例模式,static变量会在类装载时初始化,此时也不会涉及多个线程对象访问该对象的问题。虚拟机保证只会装载一次该类,肯定不会发生并发访问的问题,

因此可以省略synchronized关键字

  • 问题:如果只是加载本类,而不是要调用getInstance(),甚至永远没有调用,则会造成资源浪费
public class SingletonDemo1 {
//类初始化时,立即加载这个对象(没有延时加载的优势),,记载类时,天然的是线程安全的
private static SingletonDemo1 instance = new SingletonDemo1();
private SingletonDemo1(){ }; //方法没有同步,效率高
public static SingletonDemo1 getInstance(){
return instance;
} }

懒汉式

  • Lazy Load,延时加载,真正用到的时候再加载
  • 每次都得使用同步,synchronized,效率就底下了。
public class SingletonDemo2 {
//类初始化时,不初始化这个对象,(延时加载,真正用到的时候再创建)
private static SingletonDemo2 instance ;
private SingletonDemo2(){ }; //方法同步,效率低
public static synchronized SingletonDemo2 getInstance(){ if(instance==null){
instance= new SingletonDemo2();
}
return instance;
} }

双重检测锁

  • 双重检测判断
  • 使用volatile关键字,保证可见性
public class Singleton {
private volatile static Singleton sSingleton; private Singleton() {
} public static Singleton getSingleton() {
if (sSingleton == null) {
synchronized (Singleton.class) {
if (sSingleton == null) {
sSingleton = new Singleton();
}
}
}
return sSingleton;
}
}

静态内部类

  • 外部类没有static关键字,所以不会立即加载
  • 只有调用getInstance()时才会加载静态内部类,线程安全。instance前面加了static final关键字,因此保证了内存中只有这样一个实例存在,且只能赋值一次,final保证线程安全
  • 具有并发高效调用和延迟加载的双重优点
public class SingletonDemo3 {

    private static class SingletonClassInstance{
private static final SingletonDemo3 instance = new SingletonDemo3() ;
} private SingletonDemo3(){ } public static SingletonDemo3 getInstance(){
return SingletonClassInstance.instance;
} }

枚举实现

  • 实现简单
  • 枚举本身就是单例模式
public enum SingletonDemo4 {

    //枚举元素本身就是单例对象
INSTANCE; //添加自己需要的操作
public void singletonOperation(){ }
}

如何防止反射和反序列化漏洞

  • 反射可以破解上面几种(不包含枚举式)实现方式  --------------------------可以在构造方法中手动抛出异常控制
  • 反序列化可以破解上面几种(不包含枚举式)实现方式

-------可以通过定义readResolve()防止获得不同对象。
            --------反序列化时,如果对象所在类定义了readResolve(),定义返回哪个对象,实际是一种回调。

public class SingletonDemo5 {
//类初始化时,不初始化这个对象,(延时加载,真正用到的时候再创建)
private static SingletonDemo5 instance ;
private SingletonDemo5(){
if(instance !=null){
throw new RuntimeException();
}
} //方法同步,效率低
public static synchronized SingletonDemo5 getInstance(){
if(instance==null){
instance= new SingletonDemo5();
}
return instance;
} //反序列化时,如果定义了readResolve(),则直接返回此方法指定的对象,而不需要单独创建新的对象
private Object readResolve(){
return instance;
}
}

五种单例模式比较

单例对象占用资源少,不需要延时加载   -------枚举类好于饿汉式

单例对象占用资源大,需要延时加载      -------静态内部类好于懒汉式

最新文章

  1. js精简写倒计时函数
  2. ASProtect注册码使用教程|ASProtect SKE(加壳脱壳工具) 2.56 汉化注册版
  3. Android 4.4沉浸式状态栏的实现
  4. web前端性能优化
  5. Yii2 yii2-imagine的使用
  6. BizTalk开发系列(十) ESB Guidance安装笔记
  7. ajax post提交的方式
  8. mybatis的jdbcType类型
  9. No 11.11 in my dictionary
  10. HTTP 1.1与HTTP 1.0的比较
  11. 探讨 yum 与 rpm 的安装包数量
  12. XmlDocument加载有Xmlns的xml文档,使用Xpath
  13. error: invalid 'asm': invalid operand for code 'w'
  14. MySQL连接问题【如何解决MySQL连接超时关闭】
  15. linux如何在日志中查找关键字、前几行、结尾几行
  16. 201421123042 《Java程序设计》第3周学习总结
  17. WebAPI Angularjs 上传文件
  18. ##Django中Application labels aren't unique解决方法##
  19. H5外包团队:使用HTML5播放短视频代码分享
  20. loadrunner 参数化-如何从数据库中取数据-连接数据库进行参数化

热门文章

  1. 零基础逆向工程12_C语言06_switch语句反汇编
  2. Android用RecyclerView实现的二维Excel效果组件
  3. 【selenium学习笔记一】python + selenium定位页面元素的办法。
  4. SQL Server扩展事件system_health会话总结
  5. 两个div并列居中显示——当display:inline-block;时,两个div无法对齐即一高一矮
  6. codeforce Gym 100418K Cards (概率,数学)
  7. Maven settings.xml配置详解
  8. 剑指offer18 树的子结构
  9. 01_10_Struts2_2.1.6版本的中文问题
  10. Linux运维笔记--第二部