170728、单例模式的三种水平代码

一、单例模型具备条件:
1、私有的构造方法
2、instance(单一实例,static)和getInstance(获取实例的方法,static)必须是static
二、下面三种不同层次单例模型代码评价:
第一种,通过测试发现,虚拟机加载类的时候单例就会被初始化,有些比较费时的类,我们需要使用时才加载(比如:数据库连接,开机加速等),这时候就不太适合用这种方式
第二种,通过测试发现虚拟机加载类的时候不会初始化,只有调用了获取实例的方法时才会实例化,如果已经实例化的直接拿来用,实现了懒加载,但采用了synchronized同步的方式,性能会有所下降
第三种,通过测试发现,实现了懒加载的功能(静态内部类),也解决了第二种性能下降的问题。其实代理模型等也是可以实现的
三、总结:我们可以通过优化代码来实现性能最佳的单例模型类。推荐使用第三种方式,如果不是很费时的单例第一种也没关系。今天不举spring或jdk单例模型的实现,因为单例很好理解。值得注意的是,通过反射强制访问等,可能会破坏单例,但是是有办法避免的,后面有机会再做介绍。
四、单例模型未优化的例子(原始)
public class Singleton {
    //static
    private static Singleton instance = new Singleton();
    //私有构造方法
    private Singleton() {
    }
    //static
    public static Singleton getInstance() {
        return instance;
    }
}
五、下面是三种不同水平的单例代码(第三种性能最佳)
1)第一种:(上例及下面这个例子分析),虚拟机加载的时候就会初始化
public class SingletonObject {
        private static SingletonObject instance = new SingletonObject();
        private SingletonObject() {
        System.out.println("SingletonObject is created");
    }

    public static SingletonObject getInstance() {
        return instance;
    }
    //单独调用此方法(SingletonObject.otherMethod())时,”SingletonObject is created“也会被打印,说明虚拟机加载的时候就会初始化
    public static void otherMethod() {
        System.out.println("this is other method");
    }
}
2)第二种:使用synchronized同步,虚拟机加载的时候不初始化,调用getInstance方法时才初始化
public class LazilySingletonObject {
    private static LazilySingletonObject instance = null;
    private LazilySingletonObject() {
        System.out.println("LazilySingletonObject is created");
    }
    /*
     * 这里必须同步锁synchronized
     */
    public static synchronized LazilySingletonObject getInstance() {
        if (null == instance) {
            instance = new LazilySingletonObject();
        }
        return instance;
    }
    //单独调用此方法(LazilySingletonObject.otherMethod())时,"LazilySingletonObject is created"不会被答应,说明单例没有实例化
    public static void otherMethod() {
        System.out.println("this is other method");
    }
}
3)第三种:使用静态内部类实现赖加载,不使用synchronized,这样可以优化性能
public class OptimizedLazilySingletonObject {

    private OptimizedLazilySingletonObject() {
        System.out.println("OptimizedLazilySingletonObject is created");
    }
    //静态内部类中持有这个对象
    private static class SingletonHolder {
        private static OptimizedLazilySingletonObject instance = new OptimizedLazilySingletonObject();
    }

    public static OptimizedLazilySingletonObject getInstance() {
        return SingletonHolder.instance;
    }

}

六、测试
public class SingletonTest {

    public static void main(String[] args) {
        /**
         * 输出:Singleton is created
         * 说明获取对象的时候私有方法需要调用(很好理解)
         */
        //Singleton.getInstance();
        /**
         * 输出:SingletonObject is created
         *         this is other method
         * 说明:即使调用这个类中的其他方法,类也会立即初始化
         *         如果对于那种非常费时的初始化我们希望是用的时候才初始化(比如数据库连接等)
         */
        SingletonObject.otherMethod();
        /**
         * 实现了赖加载,使用的时候才初始化,但是使用同步锁,性能会下降
         */
        //LazilySingletonObject.getInstance();
        /**
         * 输出:this is other method
         * 说明:不用的时候,单例不会初始化
         */
        LazilySingletonObject.otherMethod();
        /**
         * 实现了赖加载,并没有影响性能
         */
        OptimizedLazilySingletonObject.getInstance();
    }

}
时间: 2024-10-31 20:09:57

170728、单例模式的三种水平代码的相关文章

设计模式之单例模式(三种实现方式)

一.单例模式要点 1.单例,顾名思义,某个类仅仅能有一个实例. 2.它必须自行创建这个唯一的实例. 3.它必须自行向整个系统提供这个实例. 二.单例模式的三种实现 1.饿汉式单例类(类载入时就初始化) 代码实现 public class EagerSingleton { //私有的类成员常量 private static final EagerSingleton SINGLETON=new EagerSingleton(); //私有的默认构造方法.此类不能被继承 private EagerSi

编程算法 - 背包问题(三种动态规划) 代码(C)

背包问题(三种动态规划) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目參考: http://blog.csdn.net/caroline_wendy/article/details/37912949 能够用动态规划(Dynamic Programming, DP)求解, 能够通过记忆化搜索推导出递推式, 能够使用三种不同的方向进行求解. 动态规划主要是状态转移, 须要理解清晰. 代码: /* * main.cpp * * Created o

单例模式的三种实现方式

一.单例模式的三种实现方式 1. 什么是单例模式 基于某种方法,实例化多次,得到同一个实例/对象 2. 为什么用单例模式 实例化多次,得到的对象属性内容都一样时,应该将这些对象指向同一个内存,即同一个实例,来节省内存空间 1. 实现单例模式方式一:类内部定义类方法实现 实现方法:类中定义了一个类方法 # 未单例模式前 import setting class Mysql: def __init__(self,ip,port): self.ip=ip self.port=port @classme

python实现单例模式的三种方式及相关知识解释

python实现单例模式的三种方式及相关知识解释 模块模式 装饰器模式 父类重写new继承 单例模式作为最常用的设计模式,在面试中很可能遇到要求手写.从最近的学习python的经验而言,singleton实现的四种方法都是python的重要特征,反过来也刚好是几种特征的最佳实现.(比如你平常开发中很难遇到几个需要写元类的地方)如果不能随手写出某种实现,说明你对于那种实现的概念还没有完全掌握.最近场通过写装饰器模式的singleton来复习装饰器概念. 1. module实现 #模块实现 from

iOS中的视图跳转的三种方式(代码跳转,根据桥跳转,按钮跳转)

#import "ViewController.h" #import "SecondViewController.h" @interface ViewController () @property (retain, nonatomic) IBOutlet UITextField *textField; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // D

java单例模式的三种实现(线程安全)

直接上代码(代码注释比较完整): 第一种: package pattern.singleton.doublecheck; public class Singleton {  // 私有化默认构造方法,防止外部生成此实例 private Singleton(){}  // 声明此单一实例 // volatile: 能够及时通知其他线程,更新其线程缓存数据 private volatile static Singleton INSTANCE;  // 向外提供此单一实例 public static

单例模式的三种写法

第一种,懒汉模式,没考虑线程安全 public class Singleton { private static Singleton _instance = null; private Singleton(){} public static Singleton CreateInstance() { if(_instance == null) { _instance = new Singleton(); } return _instance; } } 第二种,经典模式 public class S

Android合并文件的三种方式代码

amr格式的文件头是6字节,在进行文件合并的时候要减去除第一个文件以外的其他文件的文件头.下面介绍合并文件的几种方式,并通过合并amr文件来举例介绍合并文件的具体流程. 注意:不同文件的文件头是不一样的,所以在合并的时候根据不同文件相应的减去合并文件的文件头.具体你可以学习Android开发教程. 步骤一:获取要合并的文件及创建合并后保存的文件 /**用于存放要合并的文件的集合**/List<File>tempFiles=new ArrayList<File>();/**合并之后的

单例模式的三种实现 以及各自的优缺点

单例模式:单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式有三种:懒汉式单例,饿汉式单例,登记式单例. 1.懒汉式单例 public class Singleton { private static Singleton singleton; private Singleton() {} //此类不能被实例化 public static synchronized Singleton getInstance() {