文档章节

设计模式之单例模式

 张念祥A
发布于 2017/09/05 17:50
字数 1123
阅读 7
收藏 0

                                  单例模式

  • 核心:保证一个类只有一个实例,并且提供一个访问该对象的全局访问点
  • 常见应用场景:
  1. Windows的任务管理器
  2. Windows的回收站
  3. 项目中,读取配置文件的类,一般也只有一个对象,没有必要酶促使用配置文件数据,每次new一个对象去读取
  4. .........
  • 优点:由于单例模式只生成一个实例, 减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置,产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方式来解决。单例模式可以在系统设置全局的访问点,优化共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。
  • 常见的五种单例模式的实现方式:
    •  主要:
      •  饿汉式:线程安全,调用效率高,但是不能延时加载
      • 懒汉式:线程不安全,调用效率不高,但是可以延时加载
    • 其他:
      • 双重检测锁式:由于JVM底层内部模型和Java平台内存模型原因,偶尔会出问题,不建议使用
      • 静态内部类式:线程安全,调用效率高,可以延时加载
      • 枚举单例:线程安全,调用效率高,不能延时加载
  • 代码实现:
    • 饿汉式:

    public class SingletonDemo01 {

         private SingletonDemo01(){}     //将构造器私有

         private static SingletonDemo01 instance =new SingletonDemo01();

         //类加载的时候就将对象new出来,不管后面用不用

         public static SingletonDemo01 getInstance(){    //提供一个对外开放的方法用来获取对象

           return instance;

         }

    }

  •  饿汉式总结:由于类加载时是线程安全的,方法不需要同步,因为对象在类加载的时候就new出来了,以后也不能改变,所以没有延时加载的优势。
  • 懒汉式:

 

   public class SingletonDemo02 {

         private SingletonDemo02(){}     //将构造器私有

         private static SingletonDemo02 instance;

         //类加载的时候,不初始化这个对象(延时加载,真正用到的时候再创建)

         public static synchronized SingletonDemo02 getInstance(){   //提供一个对外开放的方法用来获取对象

                //方法同步,调用效率低

           if(instance==null){  //如果为null,创建对象

                instance = new SingletonDemo02();

               }

               return instance;

         }

    }

  • 懒汉式总结:懒汉式适合单线程,多线程情况下如果在创建对象实例对象时不加上synchronized,则会导致对对象的访问不是线程安全的。懒汉式是延时加载,在需要的时候才创建对象。资源利用率高了,但每次调用getInstance()方法都需要同步,并发效率低

 

  • 双重检测锁式:

public class SingletonDemo03 {

         private SingletonDemo03(){}     //将构造器私有

         private static SingletonDemo03 instance;

         //类加载的时候,不初始化这个对象(延时加载,真正用到的时候再创建)

         public static  SingletonDemo03 getInstance(){   //提供一个对外开放的方法用来获取对象

               //方法同步,调用效率低

               if(instance==null){  //Single Checked

                    synchronized (SingletonDemo03.class) {

                      if(instance==null){     //Double Checked

                           instance = new SingletonDemo03();

                          }

                    }

               }

           return instance;

         }

    }

 

  • 双重检测锁式总结:将同步内容放在了if内部,提高了执行的效率,不必每次调用对象时都进行同步,只有第一次才同步,创建了以后就没有必要了。

 

  • 静态内部类实现:

 

public class SingletonDemo04 { 

         private static class singletonSlassInstance{  //静态内部类

               private static final SingletonDemo04 instance=new SingletonDemo04();

      }

         public static SingletonDemo04 getInstance(){

               return singletonSlassInstance.instance//通过静态内部类名来调用内部类中的成员

         }

         private SingletonDemo04(){} //构造器私有

    }

    • 静态内部类方式总结:外部类无static属性,不会像饿汉式那样立即加载对象,只有真正调用getInstance(),才会加载静态内部类,加载类时是线程安全的。instance是static  final类型,保证了内存中只有这样一个实例存在,而且只被赋值一次,从而保证了线程安全性。兼并了高并发调用和延时加载的优势。而且调用效率高,并实现了延时加载。
  • 枚举方式:

public enum SingletonDemo05 {

         INSTANCE//此元素本身就是单例对象

         //添加自己需要的操作

         public void singletonOperation(){    

         }

    }

  • 枚举方式总结:
    • 优点:实现简单,枚举本身就是单例模式,由JVM从根本上提供保障,避免通过反射和反序列化的漏洞。
    • 缺点:无延时加载。

 

 

 

 

 

© 著作权归作者所有

粉丝 0
博文 2
码字总数 2531
作品 0
私信 提问

暂无文章

NIO基于长度域的报文在Netty下的解码

1, 先复习一下粘包/拆包 1.1, 粘包/拆包的含义 TCP是个“流”协议, 并不了解上层业务数据的具体含义, 它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP...

老菜鸟0217
今天
8
0
从零开始搭建spring-cloud(2) ----ribbon

在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的。Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign。 其实我们已经在上...

Vincent-Duan
今天
19
0
get和post的区别?

doGet:路径传参。效率高,安全性差(get的传送数据量有限制,不能大于2Kb) doPOST:实体传参。效率低,安全性好 建议: 1、get方式的安全性较Post方式要差些,包含机密信息的话,建议用Pos...

花无谢
昨天
4
0
当谈论迭代器时,我谈些什么?

当谈论迭代器时,我谈些什么? 花下猫语:之前说过,我对于编程语言跟其它学科的融合非常感兴趣,但我还说漏了一点,就是我对于 Python 跟其它编程语言的对比学习,也很感兴趣。所以,我一直...

豌豆花下猫
昨天
14
0
10天学Python直接做项目,我做了这5件事

初学者如何尽快上手python? 市面上关于如何学python的资料很多,但是讲的都太复杂。 我就是很简单的几句话,从小白到开发工程师,我只做了五件事。 我觉得任何商业计划书如果不能用几句话讲...

Python派森
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部