zoukankan      html  css  js  c++  java
  • 单例模式(Singleton Pattern)

    单例模式用于确保某个类全局只有一个实例。

    单例模式的最基本的UML类图:

    单例模式的最基本的代码示例:

     1 public class Singleton
     2 {
     3     private static Singleton instance = null;
     4 
     5     private Singleton() {};
     6 
     7     public static Singleton getInstance()
     8     {
     9         if(instance == null)
    10         {
    11             instance = new Singleton();
    12         }
    13         return instance;
    14     }
    15 }

    对于上面的单例模型,如果对于单线程程序来说,不会存在什么问题,但是对于多线程可能会产生多个实例,对此我们有三种不同的实现方式

    1. 饿汉实现,在声明静态属性的时候进行初始化,代码示例如下:

     1 public class EagerSingleton
     2 {
     3     private static EagerSingleton instance = new EagerSingleton();
     4 
     5     private EagerSingleton() {};
     6 
     7     public static EagerSingleton getInstance()
     8     {
     9         return instance;
    10     }
    11 }

    对于这个实现在类第一次加载的时候,静态变量instance就会被初始话,保证了实例的的唯一性,不足之处,不能实现实例的延迟创建。

    2. 懒汉实现,对get方法进行线程锁控制实现

     1 public class LazySingleton
     2 {
     3     private static LazySingleton instance = null;
     4 
     5     private LazySingleton() {};
     6 
     7     synchronized public static LazySingleton getInstance()
     8     {
     9         if(instance == null)
    10         {
    11             instance = new Singleton();
    12         }
    13         return instance;
    14     }
    15 }

    懒汉模式通过synchronized关键字解决了线程安全问题,也实现了实例的延迟创建,但是需要检测线程锁对于高并发环境性能会大大降到。

    3. IoDH实现(Initialization on Demand Holder),通过在单例类中增加增加静态内部类来实现

     1 public class IoDHSingleton
     2 {
     3     private static HolderClass
     4     {
     5         private final static IoDHSingleton instance = new IoDHSingleton();
     6     }
     7 
     8     private IoDHSingleton() {};
     9 
    10     public static IoDHSingleton getInstance()
    11     {
    12         return HolderClass.instance;
    13     }
    14 }

    对于这个实现既解决了线程安全问题,也实现了实例的延迟创建,但是不足之处很多面向对象语言不支持静态内部类的特性。

      此外,还有双重检测锁定的方式实现,但是由于双重检测锁定的方式中的,单例属性要加volatile关键字,而volatile关键字会屏蔽java虚拟机所做的一些代码优化,和锁定代码块会影响性能,所以也不是很少的方法,所以也就不做代码实现了。

      对于单例模式很多人说,单例模式长时间不用会被gc回收,我认为在Java中是不存在这种情况的,Java中单例模式创建的对象被自己类中的静态属性所引用,所以不会被回收。

  • 相关阅读:
    SpringMvc执行流程
    Lock wait timeout exceeded; try restarting transaction解决方法
    MySQL删除复杂的重复数据的解决方案(一条数据项中包含多个值的情况)
    数据移植时递归运算查询部门及其下级所有部门的问题
    IDEA常用插件
    mybatis和mybatisPlus中解决实体类字段与数据库关键字冲突问题
    时间日期操作
    spring项目中使用MD5加密方式
    idea如何调出仪表盘
    scanf使用过程中的技巧与坑位
  • 原文地址:https://www.cnblogs.com/bffc/p/3681101.html
Copyright © 2011-2022 走看看